C

时间:2016-08-08 14:41:10

标签: c pointers malloc strlen

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

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);}替换它,但它没有改变任何东西。我尝试使用temp而不是char temp[1000]声明malloc并取消free(temp);行,但它仍然执行相同的操作。如果我拿走free(temp);行仍然使用malloc问题就解决了,但是存在巨大的内存泄漏,所以我无法做到。如果有错误取决于myString字符串中的内容,这意味着如果其中存在某个值,则始终存在错误,如果存在另一个特定值,则永远不存在错误,但我无法找出哪种类型的价值观有效,哪些价值观无效,似乎是随机的。

为什么free(temp);有时会起作用,有时候不起作用,如何让它始终有效?

1 个答案:

答案 0 :(得分:5)

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

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。在取消引用返回的指针

之前检查有效的返回值