使用malloc后无法复制数组

时间:2015-08-22 09:56:55

标签: c arrays memory-management

void replace(char* str) {
    unsigned int len = 0;
    unsigned int no_of_spaces = 0;
    char* temp = str;
    int* space_positions = NULL;
    while (*temp) {
        if ((char)*temp == SPACE) {
            no_of_spaces++;
        }
        temp++;
        len++;
    }

    printf("%d\n", len); / prints correct value

    void* str_copy_allocation = (char*) malloc((sizeof(char) * len) + 1);
    char* str_copy = NULL;
    if (str_copy_allocation)
        str_copy = str_copy_allocation;
    else {
        fprintf(stderr, "Invalid allocation occured");
        perror("Error printed by perror");
    }
    temp = str; // point to starting of str
    while (*temp != '\0') {
        *str_copy++ = *temp++;
        printf("%c\n", *str_copy);
    }
    str_copy[len] = '\0';

    printf("%s\n", str_copy);

    temp = str_copy; // to the start of str_copy
    unsigned int new_len = len + 2 * no_of_spaces + 1;
    str_copy = realloc(temp, new_len);
    if (str_copy == NULL) {
        fprintf(stderr, "Invalid reallocation occured");
        perror("Error printed by perror");
    }
    str_copy[new_len] = '\0';

    printf("%s\n", str_copy);
}

这里我试图制作一个char数组的副本,然后增加它的大小。当我将Aborted (core dumped)的值复制到temp时,我收到str_copy。由于str是用户定义的字符串,为了增加它的大小,我必须复制它。该副本为str_cpy,然后我将增加str_cpy的大小并将其作为新字符串返回。

while循环中的print语句printf("%c\n", *str_copy);打印空字符!

可能是什么原因?

1 个答案:

答案 0 :(得分:3)

你有两个问题,首先是因为在行str_copy[len] = '\0';指出的用户312023已经增加了str_copy。您需要将str_copy = str_copy_allocation;放在此行上方以指向字符串的开头。

另一个问题是你的printf循环

    while (*temp != '\0') {
        *str_copy++ = *temp++;
        printf("%c\n", *str_copy);
    }

当你打印时,str_copy已经增加了,所以你要在str_copy中打印下一个字符(你还没有从temp复制过)。要查看您复制的内容,您应该在打印后增加str_copy,如此

    while (*temp != '\0') {
        *str_copy = *temp++;
        printf("%c\n", *str_copy++);
    }

通过这两项更改,代码可以正常运行。

编辑:另一个问题是,当您使用重新分配放大字符串,并将空终结符放在末尾时,您的字符串在位置str_copy[len]中已经有一个空终止符,它是从较小的位置复制的长度字符串。因此,任何作用于该字符串的函数都不会考虑您分配的额外内存,因为它们将在第一个空终止符处停止。

要显示此信息,请尝试在某些字符串上使用该函数,例如 replace("my string");

然后在函数中,在最终printf之前的末尾添加str_copy[len+1]='x';之类的内容。

你会注意到这个x没有打印,因为printf在第一个空终止符处停止,这是在'结束'在重新分配更多内存之前的字符串。如果您执行str_copy[len]='x'; str_copy[len+1]='x',则会打印两个x,因为您已覆盖从珍贵字符串复制的空终止符。

所以要解决这个问题,只需在str_copy[len]=' ';行之前或之后放置str_copy[new_len]='\0';,这将覆盖较小字符串中的空终止符。