Tuesday, August 23, 2005

Segmentation Fault - Need assistance resolving {Novice C++ Programmer}

Hello folks, I seem to have recieved a segfault within my function but
am unsure on how to resolve it. I understand that it means that
somewhere something is trying to access memory that is not prohibited
or not available.

The following function is an overloaded += operator that reads in
strings in a record format seperated by comma delimiters except for the
last data which terminates with a semicolon. I am adding these records
to an array of objects which stores the record. I hope the folowing
code is enough to identify the problem. The static array's are defined
as told in my assignment.

const char* Bank::operator+=(const char a[])
{

char stringTemp[316];
char accountTemp[16];
int balanceTemp;
const char *ptr = a;

sscanf(ptr, "%15[^,],%d,%315[^;];", accountTemp, &balanceTemp,
stringTemp);

savings[size].changeAccountNumber(accountTemp);
savings[size].changeBalance(balanceTemp);
strcat(stringTemp,";");
savings[size].changeCustomerInfo(stringTemp);
size++; //Core dump here

return a;
}
- AMT2K5

14 Comments:

At 6:44 PM, August 23, 2005, Anonymous Anonymous said...

Make sure you initiliase it using

char stringTemp[316] = {0};

> char accountTemp[16];

Same here.

> int balanceTemp;

This one is left uninitialised as well

> const char *ptr = a;

There is no need in this, is there? Why don't you just pass 'a' to the
'scanf' below?

> sscanf(ptr, "%15[^,],%d,%315[^;];", accountTemp, &balanceTemp,
> stringTemp);

> savings[size].changeAccountNumber(accountTemp);
> savings[size].changeBalance(balanceTemp);
> strcat(stringTemp,";");

Since 'stringTemp' wasn't initialised to 0 it probably concatenates the
semicolon to some unsuspecting part of memory -- undefined behaviour.

BTW, are you sure there is enough room in 'stringTemp' to append the
semicolon?

> savings[size].changeCustomerInfo(stringTemp);
> size++; //Core dump here

> return a;

> }

 
At 6:45 PM, August 23, 2005, Anonymous Anonymous said...

This function has the return value type of 'const char*'. I don't see any 'return' statement...

That may or may not be the cause of your segmentation fault. Impossible
to tell without seeing how the function is used.

 
At 6:46 PM, August 23, 2005, Anonymous Anonymous said...

Return a

 
At 6:46 PM, August 23, 2005, Anonymous Anonymous said...

I am guessing the function _now_ looks like this

const char* Bank::operator+=(const char a[])
{
size++;
return a;
}

Does it still segfault? If it does, then the problem is elsewhere.

It is _very_likely_ though, that you're calling this member function
through an invalid pointer or an invalid reference, which means that
the error lies _outside_ this function.

 
At 6:47 PM, August 23, 2005, Anonymous Anonymous said...

Learn this mantra:

Post a complete, minimal, compliable, program that demonstrates the
problem. You haven't done that here. We don't know what savings or size
are, nor do we see the input data you are running this against.

You are almost assuredly overrunning a buffer, that stringTemp stuff
looks suspicious.

 
At 6:47 PM, August 23, 2005, Anonymous Anonymous said...

There is no need to initialize them provided he checks the return value of
the sscanf call.

 
At 6:48 PM, August 23, 2005, Anonymous Anonymous said...

How is checking of sscanf return value going to help? Does sscanf put the
null terminator into the array when converting "%15[^,]"?

 
At 6:48 PM, August 23, 2005, Anonymous Anonymous said...

I can post the whole code but it was be maybe 2-3 pages or so. I dont
know if that would be breaking any rules or not.

 
At 6:49 PM, August 23, 2005, Anonymous Anonymous said...

You know, before you summon the help of the entire planet for mere 2-3
pages of code, maybe you just need to spend a bit more time in a debugger
stepping through your code and examining the values of your objects? What is your ultimate goal, to get this 2-3 pages of code to run or to become a good C++ programmer? Think about it.

 
At 6:50 PM, August 23, 2005, Anonymous Anonymous said...

You don't need to. What you need to do is reduce down the program to a
managable size first. Often in doing so you will discover the problem.
As it was, most of the objects in your code were completely undefined
to us, as was the data set.

Yes it will be extra work for you, but you're the one that want's help.

 
At 6:50 PM, August 23, 2005, Anonymous Anonymous said...

Sure it does.
http://www.opengroup.org/onlin epubs/009695399/functions/scan f.html

 
At 6:51 PM, August 23, 2005, Anonymous Anonymous said...

Ok guys, I found the source of the problem - I have commented the
function but would appreciate if you have any tips on fixing it. It
seems to be a pointer problem I believe.

It was not size++ or anything in that function I posted above. I ran a
debugger as mentioned (had to download one as I was using bcc32 in a
command prompt before).

The following function cleans up a string, I have commented important
lines

int cleanSpace(char* ptr)
{
char temp[300];
strcpy(temp, ptr);

int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; temp[i]; i++)
{
if(temp[i] == '\n' || temp[i] == '\t')
temp[i] = ' ';
}

// For loop finds character starting point.
for(i=0; temp[i] == ' '; i++)
{
temp[m] = temp[i+1];
}

// For loop moves all characters next to the first found character.
for(i++; temp[i]; i++)
{
temp[++m] = temp[i];
}
temp[m+1] = '\0';

// For loop removes trailing spaces.
for(i = strlen(temp) - 1; temp[i] == ' '; i--)
{
temp[i] = '\0';
}

// For loop removes excess spaces.
for(i = 0; temp[i]; i++)
{
if(temp[i] == ' ' && temp[i+1] == ' ')
{
j = i;

while(temp[j] == ' ')
{
j++;
}

for(k = i + 1; temp[k]; k++, j++)
{
temp[k] = temp[j];
}
j=0;
}
}
strcpy(ptr,temp); // Copy temp to ptr // Seg fault (Access
violation) happens on this line
return strlen(ptr); // Return the length

}

The segfault occurs on the strcpy(ptr,temp) right above.

 
At 6:51 PM, August 23, 2005, Anonymous Anonymous said...

it is called via cleanSpace(c);
when it is passed a string

 
At 6:52 PM, August 23, 2005, Anonymous Anonymous said...

What's "ptr"? How do you call this function? Are you sure you're allowed
to write as many characters as 'temp' has back into the location where 'ptr'
points?

 

Post a Comment

<< Home