I've got a program I've made that runs just fine, except that when it goes to return from main, it crashes. Using return 0; as the last line of code at the end of main doesn't change this, but using exit(0); does.
I'd like to use this as part of another program in a header file, so obviously I'd rather not have the program end there by calling exit(0);
Anyone have any ideas why this might be? I'm not allocating any dynamic memory in the program, and I can post the code if anyone wants to see it.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define BLANK 32
#define LOWER 0x20
#define UPPER 0xAF
#define COLS 80
#define ROWS 24 //this can be changed
#define MROW 11 //must be greater than stringlength
#define MCOL 30
#define MLEN 20
#define MLINE 2
#define CCHAR 0xDB
#define STRINGLENGTH 10
#define SECS 35.0
#define RANDRANGE 2*ROWS
int rb (int lo, int hi)
{
return rand()%(hi-lo+1)+lo;
}
int inmcol (int i)
{
return (i>=MCOL&&i<MCOL+MLEN);
}
int inmrow (int i)
{
return (i>=MROW&&i<MROW+MLINE);
}
int Check(int value, int*A)
{
for (int i=0;i<COLS;i++)
if(A[i]<=value)
return 0;
return 1;
}
int main()
{
system("color 0A");
char screen[ROWS][COLS];
int i,j,k;
int chpos [COLS];
char message [MLINE][MLEN+1]={" T h e M a t r i x ", " U N L O A D E D "};
time_t start, now;
double diff;
start = time (NULL);
srand(time(NULL));
for (i=0;i<ROWS;i++)//setup screen
for(j=0;j<COLS;j++)
screen[i][j]=BLANK;
for (k=0;k<COLS;k++)//set positions of changing characters
{
chpos[k]=rb(-RANDRANGE,0);
}
do
{
for (i=0;i<COLS;i++)//change characters
{
if (chpos[i]>=0)
{
screen[chpos[i]][i]=(char)rb(LOWER,UPPER);
}
if (chpos[i]<0)
{}
elseif (chpos[i]>=STRINGLENGTH)
{
screen[chpos[i]-STRINGLENGTH][i]=BLANK;
}
else
{
screen [ROWS+chpos[i]-STRINGLENGTH][i]=BLANK;
}
chpos[i]++;
if(chpos[i]==ROWS)
chpos[i]=0;
if (chpos[i]>=0)
{
screen[chpos[i]][i]=CCHAR;
}
}
system("CLS");
for (i=0;i<ROWS;i++)//print screen
for(j=0;j<COLS;j++)
printf("%c",screen[i][j]);
now=time(NULL);
diff=difftime(now,start);
}while(SECS>diff);
k=0;
while(k++<ROWS || !Check(ROWS+STRINGLENGTH,chpos))//this starts displaying the title
{
for (i=0;i<COLS;i++)//change characters except message characters
{
if (inmrow(chpos[i])&& inmcol(i))//in the message area
{
screen[chpos[i]][i]=message[chpos[i]-MROW][i-MCOL];
//print part of the message
}
elseif (chpos[i]<ROWS)//if valid area
{
screen[chpos[i]][i]=(char)rb(LOWER,UPPER);
}
if (inmrow(chpos[i]-STRINGLENGTH)&& inmcol(i))//in the message area
{
//don't blank out anything, it's part of the message
}
elseif (chpos[i]>ROWS+STRINGLENGTH)//chpos is way below the screen
{
}
elseif (chpos[i]>=STRINGLENGTH)//something needs blanking
{
screen[chpos[i]-STRINGLENGTH][i]=BLANK;
}
else//something needs blanking near the bottom
{
screen [ROWS+chpos[i]-STRINGLENGTH][i]=BLANK;
}
chpos[i]++;
if(chpos[i]==ROWS&&k<ROWS)//if we haven't looped once already
{
chpos[i]=0;
}
if (chpos[i]<ROWS)//set the new chpos character to CCHAR
{
screen[chpos[i]][i]=CCHAR;
}
}
//print screen
system("CLS");
for (i=0;i<ROWS;i++)
for(j=0;j<COLS;j++)
printf("%c",screen[i][j]);
}
//Pause();
//exit(0); //this exits without crashing
//return 0; //this doesn't fix the random crash
//break;
}
But it's impossible to tell without seeing any code.
EDIT-
Yes I'm almost positive it's stack corruption. I can't spot the cause of it because of the code volume.
What's happening is you're going out of bounds in one of your arrays. Since your arrays are stored locally (on the stack), this overwrites other data that the program uses when it exits the funciton -- which is why you don't see the effects until you return. Calling exit() does not solve the problem, it simply hides it.
One way to find the problem is comment out all the writes you do to all of your arrays. When you compile and run the program, it should no longer crash. Then uncomment the writes one by one, testing the program after each one until you find out which line is causing the problem. Once you know which line it is, look it over very carefully to make sure you're never stepping outside the array boundaries.
It's possible that more than one write is causing a problem. So even if you find and fix one of them, don't stop checking the rest of them.