我有一个c函数,我想返回一个字符串。
如果我在返回之前打印字符串,那么我会看到croc_data_0186.idx
如果我尝试打印返回的字符串,那么我会看到croc_data_á☼
谁能看到我做错了什么?
问题功能:
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;
}
致电代码:
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);
...
}
答案 0 :(得分:7)
您正在返回指向本地数据的指针,该指针在函数返回后无效。你必须正确分配字符串。
这可以在调用函数中完成,通过向被调用函数提供缓冲区,并将字符串复制到提供的缓冲区。像这样:
char segmentFileName[SOME_SIZE];
getSegmentFileName(file, lineLength, mid, segmentFileName);
和getSegmentFileName
函数:
void getSegmentFileName(FILE *file, int lineLength, int lineNumber, char *segmentFileName)
{
/* ... */
strcpy(segmentFileName, fileNameString);
}
另一种解决方案是在getSegmentFileName
:
return strdup(fileNameString);
但是你必须记住以后free
字符串。
答案 1 :(得分:4)
这是因为你要返回一个指向local的指针。这是未定义的行为。
strtok
返回指向line
字符数组的指针。您将该指针放入fileNameString
,然后返回给调用者。此时line
内的内存变为无效:可以将任何垃圾写入其中。
要避免此问题,您应该为返回值传递缓冲区/长度对,或者对要返回的字符串使用strdup()
。在后一种情况下,您应该记住通过strdup()
释放为返回的字符串分配的内存。
在相关主题上,您应该避免使用strtok
,因为它不是可重入的,并且会在多线程环境中引起问题。请考虑改为使用strtok_r
。
答案 2 :(得分:3)
当函数返回时,您将返回指向不再存在的局部变量的指针。你必须malloc
存储并返回它。或者,您可以让调用者在缓冲区中传递以进行填充。在任何情况下,调用者都要负责free
以后的内存。
答案 3 :(得分:2)
这是因为你返回了无效指针。
char* fileNameString;
只是一个指针。
char line[lineLength];
生活在筹码堆上并填充fgets()
电话。
char *lineElements[3];
lineElements[0] = strtok(line, ":");
lineElements[1] = strtok(NULL, ":");
lineElements[2] = strtok(NULL, ":");
这里存储指向该数组的指针。其中之一是
fileNameString = lineElements[2];
你
return fileNameString;
之后。
解决方案是
在函数内部使用malloc足够的空间并将字符串复制到新的内存块或
让调用者提供您将数据写入的缓冲区。
答案 4 :(得分:2)
问题是你正在返回一个堆栈变量,当函数返回时会丢失。一种方法是在函数参数中使用char * arg,并有足够的保留空间,并使用它来存储所有信息并将其返回。
答案 5 :(得分:0)
Line是一个局部变量,在函数末尾被删除。
你应该使用malloc,或者将它strcpy到作为参数传递的字符串指针。
答案 6 :(得分:0)
有三种方法可以解决这个问题
1)使'fileNameString'静态
static char fileNameString[100];
2)函数'getSegmentFileName'的调用者应该将字符缓冲区'segmentFileName'传递给被调用者,即
getSegmentFileName(file, lineLength, mid, segmentFileName);
在这种情况下,您需要更改函数参数
char* getSegmentFileName(FILE *file, int lineLength, int lineNumber, char *segmentFileName) {
.....
strcpy(segmentFileName, fileNameString); // copying the local variable 'fileNameString' to the function argument
// so that it wont be lost when the function is exited.
return fileNameString; // there is no need to return anything and you can make this function void
// in order not to alter ur program I am putting the return also
}
3)通过这种方式,您可以为fileNameString动态分配内存。动态内存在堆中分配,并且在函数返回时不会丢失。所以你可以在indexSearch函数中安全地使用它。
char* getSegmentFileName(FILE *file, int lineLength, int lineNumber)
{
char *fileNameString = (char *)malloc(100 * sizeof(char)); // allocate memory for 100 character string
.....
return fileNameString;
}
在这种情况下,您需要使用free