C scanf覆盖全局声明的结构数组

C scanf overwriting globally declared array of structs

我发现在将字符串扫描到缓冲区时我的结构数组被覆盖,我可能以某种方式共享相同的内存,但我不知道如何修复它。

Struct and array of structs global declaration

struct Node {
    int number;
    char *string;
};


struct Node nodes[50] = {{ 0 }};

...一些对数组中节点的操作...

insert function

void insert(char *string, int number)
{
nodes[lastIndex].number = number;
nodes[lastIndex].string = string;

Now I scan string into buff

char buff[20]

while (scanf("%s", buff) > 0)
    {
        if (!strcmp(buff, "print"))
            printf("%s", printhighest());
        else
        {
            scanf("%s %d", buff, &number);
            insert(buff, number)
        }
    }

每次第一个条件适用时,结构数组中的 char* 字符串会在数组的每个元素上被字符串 "print" 覆盖。

随着 while 循环在 scanf("%s", buff)

之后开始,它会立即发生变化

所以当我想打印时,它看起来像这样:

节点[0] - 数字(10) - 字符串("print")
节点[1] - 数字(25) - 字符串("print")
等等...

顺便说一句,我无法更改 while 循环。

感谢您的帮助。

问题出在这一行:

nodes[lastIndex].string = string;

请注意 char* 本身并不是字符串,而实际上只是指向位于内存中某处的某个字符数组的指针。

通过上述分配,所有节点都指向完全相同的内存位置 buff,因此所有节点都看到那里写入的完全相同的文本 - 当您最终想要打印时将得到 "print":

buff  <----------------
            |    |     |
nodes[0].string  |     |
      nodes[1].string  |
          nodes[2].string
            .
             .
              .

要解决这个问题,需要为字符串创建新的内存并将buff的内容复制到;使用 strdup 函数最容易完成:

nodes[lastIndex] = strdup(buff);

或者,复制已经在外面的字符串:

insert(strdup(buff), number);

请注意 strdup 会分配新内存,因此不要忘记在不再需要时再次释放字符串以防止内存泄漏。