从C中的函数返回一个字符串

我有一个ac函数,我想返回一个字符串。

如果我在返回之前打印字符串,那么我会看到croc_data_0186.idx

如果我尝试打印返回的字符串,那么我会看到croc_data_á☼

谁能看到我做错了什么?

问题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; } 

调用代码:

 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); ... } 

您正在返回指向本地数据的指针,该指针在函数返回后无效。 您必须正确分配字符串。

这可以在调用函数中完成,通过向被调用函数提供缓冲区,并将字符串复制到提供的缓冲区。 像这样:

 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字符串。

这是因为您正在返回指向local的指针。 这是未定义的行为。

strtok返回指向line字符数组的指针。 您将该指针放入fileNameString ,并返回给调用者。 此时内线内存变为无效:可以将任何垃圾写入其中。

要避免此问题,您应该为返回值传递缓冲区/长度对,或者对要返回的字符串使用strdup() 。 在后一种情况下,您应该记住通过strdup()释放为返回的字符串分配的内存。

在相关主题上,您应该避免使用strtok ,因为它不是可重入的,并且会在multithreading环境中引起问题。 请考虑使用strtok_r

您正在返回指向函数返回时不再存在的局部变量的指针。 你必须为它进行malloc存储并返回它。 或者,您可以让调用者通过缓冲区来填充。 在任何情况下,调用者都有责任以后free内存。

这是因为你返回了无效的指针。

  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足够的空间在函数内部,要么将你的字符串复制到新的内存块或

  • 让调用者提供您将数据写入的缓冲区。

问题是你返回一个堆栈变量,当函数返回时丢失。 实现此目的的一种方法是在函数参数中使用char * arg,具有足够的保留空间,并使用它来存储所有信息并将其返回。

Line是一个局部变量,在函数末尾被删除。

你应该使用malloc,或者将它strcpy到作为参数传递的字符串指针。

有3种方法可以解决这个问题

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 fileNameString指向的内存