C _platform\u memmove$VARIANT$Unknown(),来自/usr/lib/system/libsystem\u platform.dylib更改字符指针的内容

C _platform\u memmove$VARIANT$Unknown(),来自/usr/lib/system/libsystem\u platform.dylib更改字符指针的内容,c,C,我试图编写一个程序,接受一个用户字符串,然后颠倒字符串中单词的顺序并打印它。我的代码适用于大多数尝试,但是,对于相同的输入,它在某些情况下会区分错误 单步执行时,我发现字符指针单词[0]和单词[1]的内容变为垃圾值/Null 我在一个单词[1]和wprd[0]字符指针上设置了一个观察点,这些指针正在损坏(地址不正确),并且可以看到这些指针的内容在“\u platform\u memmove$VARIANT$Unknown()(来自/usr/lib/system/libsystem\u platf

我试图编写一个程序,接受一个用户字符串,然后颠倒字符串中单词的顺序并打印它。我的代码适用于大多数尝试,但是,对于相同的输入,它在某些情况下会区分错误

单步执行时,我发现字符指针单词[0]和单词[1]的内容变为垃圾值/Null

我在一个单词[1]和wprd[0]字符指针上设置了一个观察点,这些指针正在损坏(地址不正确),并且可以看到这些指针的内容在“\u platform\u memmove$VARIANT$Unknown()(来自/usr/lib/system/libsystem\u platform.dylib”处发生了更改。我不知道如何调用它,以及是什么导致指针的内容被覆盖

我已经在下面发布了我的代码,并希望得到任何帮助来找出我的错误所在。我对缩进问题感到抱歉

char* reverseWords(char *s) {
    char** words = NULL;
    int word_count = 0;

    /*Create an array of all the words that appear in the string*/
    const char *delim = " ";
    char *token;
    token = strtok(s, delim);
    while(token != NULL){
        word_count++;
        words = realloc(words, word_count * sizeof(char*));
        if(words == NULL){
            printf("malloc failed\n");
            exit(0);
        }
        words[word_count - 1] = strdup(token);   
        token = strtok(NULL, delim);
    }

    /*Traverse the list backwards and check the words*/
    int count = word_count;
    char *return_string = malloc(strlen(s) + 1);
    if(return_string == NULL){
        printf("malloc failed\n");
        exit(0);
    }
    int offset = 0;
    while(count > 0){
        memcpy((char*)return_string + offset, words[count - 1], strlen(words[count - 1]));
        free(words[count - 1]);
        offset += strlen(words[count - 1]);
        if(count != 1){
            return_string[offset] = ' ';
            offset++;
        }
        else {
            return_string[offset] = '\0';
        }
        count--;
    }
    printf("%s\n",return_string);
    free(words);
    return return_string;
}

int main(){
    char *string = malloc(1000);
    if(string == NULL){
        printf("malloc failed\n");
        exit(0);
    }
    fgets(string, 1000, stdin);
    string[strlen(string)] = '\0';
    reverseWords(string);
    return 0;
}

问题是这条线

char *return_string = malloc(strlen(s) + 1);
没有分配足够的内存来保存输出。例如,如果输入字符串为“Hello world”,则
strlen(s)
应为11。但是,
strlen将实际返回5

为什么??因为strtok
修改了输入行。每次调用strtok时,它都会找到第一个分隔符并将其替换为NUL字符。因此,在第一个
while
循环之后,输入字符串如下所示

Hello\0world\0
对该字符串调用strlen将返回5

因此,
result\u字符串
太小,一个或多个
memcpy
将写入字符串末尾,导致未定义的行为,例如分段错误。关于
memmove
的错误消息的原因是:
memcpy
函数根据需要在内部调用
memmove


正如@WhozCraig在评论中指出的,您还需要确保在调用
free
后不会访问内存,因此您需要交换这两行

free(words[count - 1]);
offset += strlen(words[count - 1]);

这段代码中的担忧包括:
free(单词[count-1]);偏移量+=strlen(字数[count-1])-Um。你只要
免费
'd
单词[count-1]
。后续访问调用未定义的行为。与之无关,
string[strlen(string)]='\0'是没有意义的
strlen(string)
正是nullchar终止符最好的位置。如果你这样做的目的是为了剔除尾随的新行,那就不是这样做的。谢谢!在这里发布代码之前匆忙添加了免费代码。但是谢谢你指出了这个明显的错误!