我可以/应该释放由strtok返回的指针吗?

3
我正在动态创建字符串数组,然后为该数组中的每个元素分配一个指向调用strtok返回的指针。在整个过程结束时,当我需要重新进行所有操作时,我一直试图释放所述数组中元素中的指针,但我一直收到错误消息:

*** glibc detected *** ./prgm: munmap_chunk(): invalid pointer: 0x00007fff600d98

另外,在循环结束时释放inputStr是否有意义?

我的逻辑“实际上并不合理”的想法错在哪里.. 例如代码

   char** argvNew = (char**)calloc(33,sizeof(char*));
   char inputStr[128];  
   do{    
        scanf("%127[^\n]%*c", inputStr);
        token = strtok(inputStr, delim);

        /* Add tokens to array*/
        varNum= 0;
        for(i = 0; token != NULL; i++){
            varNum++;
            argvNew[i] = token;
            token = strtok(NULL, delim);
        }
        argvNew[i] = NULL;

       //Free argvNew 
        for(i = 0; i < varNum;i++){
            printf("Deleting %i, %s\n",i,argvNew[i]);
            free(argvNew[i]);
        }
  while(1);

我为我的低级 C 抱歉,因为我一直在过多地编写 Java。 - Javant
3个回答

7
不,你不应该释放它。它返回一个指向中字符的指针(或在结尾处返回)。它不会分配任何新的内存,因此没有需要释放的内容。
如果是动态分配的,那么当你使用完它后应该释放它。

那么下一次循环迭代时,我就不会发生内存泄漏了吗? - Javant
如果你没有分配任何内存,那么如何产生内存泄漏? - Barmar
我怎么会这么蠢..就这样发生了。 - Javant
1
@Javant 不要责备自己。我认为这是一个很好的问题,大多数来自 [tag:java] 的人都应该有这种问题!这就是我给你点赞的原因! - gsamaras

4
不,因为它没有分配新的内存。
引用 strtok()的参考文献
返回值 如果找到令牌,则返回指向令牌开头的指针。否则,返回空指针。在扫描的字符串中到达字符串的末尾(即空字符)时,始终返回空指针。
该参考文献的示例未释放strtok()返回的内容,这证实了上述说法。
/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

你会看到strtok()返回的指针只用于访问程序已经创建的内存(无论是动态创建还是静态创建都一样)。它不会被分配新创建的内存,因此你不应该释放它。
通常情况下,你应该记住以下内容:
每次调用malloc()时,都要调用free()相同的次数。

但有时函数会在内部调用malloc()。例如,strdup() - Barmar
又是一个非标准的 [tag:c] 函数 BarmaR,但总的来说你是对的。然而问题是关于 strtok() 的。我希望我回答了你的疑虑。让我们试着对初学者来说保持合理吧! :) - gsamaras

-1

你只分配了argvNew数组。这是你唯一需要释放的。

你没有分配argvNew指针所指向的内容,因此你不应该使用free()来释放它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接