包含C中的Structs的Array中的值错误

时间:2018-01-15 14:16:45

标签: c arrays visual-studio pointers struct

我有这个结构:

(struct.h)

#pragma once

#ifndef STRUCT_H
#define STRUCT_H

typedef struct {
    unsigned int id;
    char *name;
    char *address;
} Struct;

#endif 

我制作了一个包含这些结构的动态数组。我还有一个循环,将一些数据放在这些结构中:

(main.c中)

#include <stdio.h>
#include <stdlib.h>
#include "struct.h"

int main() {

    int nStructs = 3;

    Struct *structArray = calloc(nStructs, sizeof * structArray);

    char input[30];

    for (int i = 0; i < nStructs; i++) {
        structArray[i].id = i;
        sprintf(input, "name_%d", i);
        structArray[i].name = input;
        sprintf(input, "addr_%d", i);
        structArray[i].address = input;
    }

    for (int i = 0; i < nStructs; i++) {
        printf("\n[%04d]    ID: %d\n", structArray[i].id, structArray[i].id);
        printf("[%04d]  NAME:   %s\n", structArray[i].id, structArray[i].name);
        printf("[%04d]  ADDR:   %s\n", structArray[i].id, structArray[i].address);
    }

    free(structArray);
    return 0;
}

当我尝试运行此代码时,'int ID'以正确的方式打印,但'char * name'和'char * address'都包含循环中的最后一个值(在本例中为“addr_3”) “):

(输出)

[0000]  ID:     0
[0000]  NAME:   addr_2
[0000]  ADDR:   addr_2

[0001]  ID:     1
[0001]  NAME:   addr_2
[0001]  ADDR:   addr_2

[0002]  ID:     2
[0002]  NAME:   addr_2
[0002]  ADDR:   addr_2

我尝试在visual studio中使用调试器,当它们放入数组(首先是for循环)时看起来值是正常的,但是它们在某些时候会被覆盖。由于我是visual studio的新手,我不知道如何在特定点看到数组的值而不仅仅是值[i]。

我在这里做错了什么?

编辑: 我从我的主项目中复制/粘贴了这段代码,所以只有我测试的部分才会出现在问题中。但我看到我忘了添加'free(structArray);'在'return 0;'之上。它现在在问题中添加,所以其他人不会犯同样的错误。

2 个答案:

答案 0 :(得分:2)

几乎准备好了一个例子,但后来我发现了你的评论。

不,calloc为您的结构分配空间,但不为字符串分配空间 - 您的结构只存储指针。

如果您不想更改结构,则应为每个字符串分配内存,然后复制它而不是在所有情况下将指针存储到同一元素(在您的情况下,所有指针都指向{{ 1}})。 input将为您完成:

strdup

您可能想查看指针在C / C ++中的确切运作方式。

答案 1 :(得分:1)

您需要使用malloc为结构中的所有字符串分配内存,或者将结构的定义更改为:

typedef struct {
    unsigned int id;
    char name[100];
    char address[100];
} Struct;

目前,struct中的所有char指针都指向输入,因此输入会更改struct更改中所有字符串的值。

要在不更改结构定义的情况下使代码正常工作,请执行以下类似操作:

for(int i = 0; i < nStructs; i++)
{
    structArray[i].name = malloc(100);
    structArray[i].address = malloc(100);
}

您可以在相同的for循环中执行此操作,并仅为每个字符串分配所需的内存。一定要检查malloc()是否返回NULL。