【问题标题】:C pointer to pointer overwriting last one savedC指针覆盖最后一个保存的指针
【发布时间】:2018-12-12 07:13:49
【问题描述】:

我想要做的是获取字符串,将其保存到字符串数组中,然后根据索引修改每个副本。

我编辑了问题和代码,内容混乱且不清楚。由于问题几乎相同(我认为现在更准确),我想我可以在这里完全编辑它而无需创建新问题,但如果我必须做不同的事情,请告诉我。

问题(编辑):在阅读给出的答案、创建一个 MVCE 并阅读 this 和一些调试技巧之后,我想我在指针和 strcpy 上做的一团糟......为什么下面的代码(编辑为 MVCE)会给出这个输出?

abc
x 
x
y

它可以编译并且没有调试错误,但我希望代码将 line_ret 中字符串的第一个字符更改为“x”,如果 index==0,如果 index==1,则更改为“y”。 我读过here 无法更改指针指向的单个字符,但是如果我不知道必须将 line_read 复制到 line_ret 多少次,因此不知道要声明的最大索引大小怎么办数组 line_ret?

代码(编辑)

#include<string.h>
#include<stdio.h>
#include<stdlib.h>

size_t len = 10;

int main(void){
    char *line_read = malloc(5);
    strcpy(line_read, "abc");
    char **line_ret = malloc(5 * sizeof(char*));
    int index = 0;

    while(index < 2){
        line_ret[index] = realloc(line_ret, 1*len);

        memcpy(&line_ret[index], &line_read, len);
        printf("%s\n", line_ret[index]);

        if(index == 0){
            strcpy(&line_ret[index][0], "x");
        } else if(index == 1){
            strcpy(&line_ret[index][0], "y");
        }
        printf("%s\n", line_ret[index]);

        index++;
    }

    free(line_read);
    free(line_ret);

    return 0;
}

【问题讨论】:

  • 那堵文字不可读,第一行代码已经不正确,如果你分配的是char **,则元素大小是sizeof(char *),而不是sizeof(char)
  • 如果您正在寻求调试程序的帮助,您必须发布minimal reproducible example。另外,问题到底是什么?您的帖子有一个非常长的段落难以阅读,请尝试使用一些标点符号并将其分成多个段落。
  • @FBergo 我尽量描述情况,我会调整文本大小并给出段落。这是一个拼写错误,对不起,我现在就改正它。
  • @jwdonahue 问题写在粗体字“问题”之后。如果问题还不清楚,请告诉我。我现在将提供段落。
  • 发布编译和演示问题的代码。当您将其剥离为 MCVE 时,您可能已经自己发现了缺陷。

标签: c pointers memcpy strcpy


【解决方案1】:

如果您将地址(存储在指针中)复制到数组中的多个条目,但它们都指向同一块内存(即地址相同),那么使用该数组中的不同条目将始终导致相同一块内存被覆盖。

通过比较/打印存储在数组中不同条目中的地址来进行调试。该错误是两个数组条目包含相同的地址。

要解决此问题,请确保数组中的条目接收不同的地址,即引用单独分配的内存块。
这意味着每次更改用于访问数组的索引时,您还需要 malloc 一块新的内存以与该不同的数组条目一起使用。

【讨论】:

  • 嗯,我明白了,非常感谢。我在输入 if 后尝试重新分配,但进程崩溃。我会调试并找到一些解决方案。再次感谢。
  • 感谢(已经)接受。我实际上希望您提供更多信息,最好是 MCVE。
  • 做一些调试是个好主意。如果您发现一些东西并将其添加到问题中,它可能会获得更多,可能更详细的帮助。如需调试方面的帮助,因为我真的很想提供帮助,请查看以下文本:ericlippert.com/2014/03/05/how-to-debug-small-programsericlippert.com/2014/03/21/find-a-simpler-problem(我也考虑调试建议)。
  • 我接受了,因为您向我提供了正确的信息,以便继续研究解决方案。我正在研究 MCVE,但正如其他人指出的那样,我可能能够在创建它时找到解决方案。不过,一旦我有了 MCVE,我就会编辑我的问题。
  • 是的。制作 MCVE 通常是一种出色的调试方法。 ;-) 祝你好运。
猜你喜欢
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多