c - 使用 malloc 后无法复制数组

标签 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 数组,然后增加它的大小。当我将 temp 的值复制到 str_copy 时,我得到了 Aborted (core dumped)。由于 str 是用户定义的字符串,为了增加它的大小,我必须复制它。该副本是 str_cpy,然后我将增加 str_cpy 的大小并将其作为新字符串返回。

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

可能是什么原因?

最佳答案

您有两个问题,首先正如 user312023 在 str_copy[len] = '\0'; 行中指出的那样 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("我的字符串");

然后在函数中,在最后的 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'; 行之前或之后,这将覆盖较小字符串的空终止符。

关于c - 使用 malloc 后无法复制数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32154762/

相关文章:

javascript - 如何限制 JavaScript 游戏中的子弹数量?

java - 从以 "name:"开头的字符串中获取参数

android - 内存全是图片,可能是Bitmap.compress(format, int, stream)引起的

iPhone:工具配置稳步增长

c++ - 这是否被认为是内存泄漏?

c - 在c中使用多个线程读取多个文件

c - 此功能在某些目录中无法正常工作

c - 使用链表结构跟踪 C 程序中可能的内存泄漏

C - 将可变参数列表写入文件

javascript - 加载显示在 react 中映射项目的所有按钮上