I have a c function that I want to return a string.
If I print the string before it is returned then I see croc_data_0186.idx
If I try and print the string that is returned then I see croc_data_á☼
Can anyone see what I am doing wrong?
Problem function:
char* getSegmentFileName(FILE *file, int lineLength, int lineNumber)
{
char* fileNameString;
fseek(file, lineNumber * lineLength, SEEK_SET);
char line[lineLength];
fgets(line, lineLength, file);
char *lineElements[3];
lineElements[0] = strtok(line, ":");
lineElements[1] = strtok(NULL, ":");
lineElements[2] = strtok(NULL, ":");
fileNameString = lineElements[2];
printf ("getSegmentFileName fileNameString is: %s \r\n", fileNameString);
return fileNameString;
}
Calling code:
int indexSearch(FILE *file, char* value, int low, int high, char* segmentFileName)
{
...
segmentFileName = getSegmentFileName(file, lineLength, mid);
printf ("indexSearch: segmentFilename3 is: %s \r\n", segmentFileName);
...
}
You are returning a pointer to local data, which is not valid after the function returns. You have to allocate the string properly.
This can be done in either the calling function, by supplying a buffer to the called function, and it copies the string over to the supplied buffer. Like this:
char segmentFileName[SOME_SIZE];
getSegmentFileName(file, lineLength, mid, segmentFileName);
and the getSegmentFileName
function:
void getSegmentFileName(FILE *file, int lineLength, int lineNumber, char *segmentFileName)
{
/* ... */
strcpy(segmentFileName, fileNameString);
}
The other solution is to allocate the memory for the string in getSegmentFileName
:
return strdup(fileNameString);
but then you have to remember to free
the string later.
This is because you are returning a pointer to local. This is undefined behavior.
strtok
returns a pointer into the line
character array. You put that pointer into fileNameString
, and return to the caller. At this time the memory inside line
becomes invalid: any garbage can be written into it.
To avoid this problem, you should either pass a buffer/length pair for the return value, or use strdup()
on the string that you are returning. In the later case you should remember to free the memory allocated for the returned string by strdup()
.
On a related subject, you should avoid using strtok
, because it is not re-entrant, and will cause issues in multithreaded environments. Consider using strtok_r
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With