【问题标题】:Problems with free() function in C [closed]C中free()函数的问题[关闭]
【发布时间】:2016-08-08 14:41:10
【问题描述】:

我在for 循环中有一个while 循环来处理字符串。这里基本上是我的代码结构:

char myString[1000];
//Initialize and maybe change myString
for(/*conditions*/){
    while(/*conditions*/){
        if(strchr(myString,' ') == NULL){
            break;
        }
        char *temp = malloc(sizeof(char) * strlen(myString));
        strcpy(temp,myString);
        *strchr(temp,' ') = '\0';
        strcat(myString," ");
        strcat(myString,temp);
        free(temp);
    }
}

有时,这段代码工作得很好,但有时进程结束并返回 3,这意味着有一个错误(3 是我通常在我不应该喜欢的地方尝试使用 NULL 时得到的返回值myPointer->example 其中myPointer 为NULL)。经过一些测试,我发现导致问题的行是free(temp);。我试图用if(temp != NULL){free(temp);} 替换它,但它没有改变任何东西。我试图用char temp[1000] 而不是malloc 声明temp 并删除free(temp); 行,但它仍然做同样的事情。如果我拿走free(temp); 行并仍然使用malloc,问题就解决了,但是存在巨大的内存泄漏,所以我不能这样做。是否有错误取决于myString字符串中的内容,这意味着如果其中有某个值,则总是有错误,如果有另一个特定值,则永远不会有错误,但我无法找出哪些类型的值有效,哪些无效,这似乎是随机的。

为什么free(temp); 有时有效,有时无效,我怎样才能让它始终有效?

【问题讨论】:

  • char *temp = malloc(sizeof(char) * strlen(myString)); strcpy(temp,myString); 越界写入,未定义行为。此外,如果strchr() 返回NULL,则NULL-dereference 的未定义行为。
  • 另外,sizeof( char ) 根据定义是一个,因此它作为传递给malloc() 的参数的一部分是多余的。
  • 我投票结束这个问题,因为这个问题是由一个简单的错字引起的。

标签: c pointers malloc strlen


【解决方案1】:

主要问题是,您分配的元素少于所需的内存。

strlen() 不考虑终止空值,因此您缺少所需的内存。后来,做

strcpy(temp,myString);

实际上是调用undefined behavior的越界访问(存储终止的空值)。结果,你可以看到

有时,这段代码可以正常工作,但有时进程结束并返回 3,这意味着存在错误[....]

要解决,你应该修改分配语句,如

char *temp = malloc(strlen(myString) + 1); // +1 for terminating null,
                                           // sizeof(char) == 1, guaranteed by C standard.

也就是说,来自man page

strchr()strrchr() 函数返回一个指向匹配字符的指针如果找不到该字符,则返回 NULL。 [...]

对于突出显示的场景,

*strchr(temp,' ') = '\0';

尝试取消引用无效的空指针常量 (NULL) 并再次调用 UB。在取消引用返回的指针之前检查有效的返回值

【讨论】:

  • ....如果出现 UB,任何预期或意外的结果都可能发生。
  • @hacks 是的,先生,刚刚引用了问题中的部分来说明这一点。 :)
  • @DonaldDuck 检查答案中的编辑,如果问题仍然存在,请创建一个 MCVE。
  • @SouravGhosh 我一开始就已经用if(strchr(myString,' ') == NULL){break;} 处理过这个问题。所以strchr(test,' ') 不应该为 NULL,因为此时 test 和 myString 是相同的,如果 myString 中没有任何空格,它就会退出 while 循环。
  • @DonaldDuck 说得通,删除了那个选项。
猜你喜欢
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多