C结构,内存分配和结构

时间:2013-04-03 17:02:28

标签: c malloc structure

因此,任务是读取文件并将数据推送到结构。数据文件是:

babe 12 red 12
deas 12 blue 12
dsa 12 red 512
bxvx 15 blue 52
reed 18 black 15

虽然代码是那样的

struct shoes {
    char name[8];
    int size;
    char color[8];
    int price;       
};
//open file
shoes *item=(struct shoes*)malloc(sizeof(struct shoes));
for (i=0; !feof(file); i++) {
    item=(struct shoes*)realloc(item,sizeof(struct shoes)+i*sizeof(struct shoes));
    fscanf(file,"%s %i %s %i\n",(item+i)->name,(item+i)->size,(item+i)->color,(item+i)->price);
}

但程序每次都会崩溃。 dbg说:当前上下文中没有符号“item”。 错误在哪里?

4 个答案:

答案 0 :(得分:3)

问题是你没有将指针传递给你想要使用fscanf读取的整数,而是自己传递整数。

fscanf将它们视为指针。他们指向哪里?谁知道 - 整数是未初始化的,所以他们可以指出 ANYWHERE 。因此, CRASH

明确修复:

fscanf(file,"%s %i %s %i\n",
    (item+i)->name,
    &((item+i)->size),
    (item+i)->color,
    &((item+i)->price));

请注意,namecolor不需要相同,因为数组会退化为指针,因此您已经传递了正确的内容。

请考虑放弃item+i符号;随便阅读代码时,item[i] 所以更清晰,更容易理解:

fscanf("%s %i %s %i\n", 
    item[i].name, 
    &item[i].size, 
    item[i].color,
    &item[i].price);

答案 1 :(得分:3)

您的代码有一些错误: 1)除非你使用C ++编译器进行编译,否则你需要一个typedef for shoes ...但是你应该标记这个C ++。 2)feof不会返回false,直到实际上已经尝试读取超出文件末尾的次数,因此你的代码会使鞋子1的数组太大。 3)你正在通过fscanf而不是他们的地址。

如果编译为C代码而不是C ++代码,则不需要对malloc和realloc进行转换,建议不要使用。还有其他风格问题会让你难以理解你的代码。试试这个:

typedef struct {
    char name[8];
    int size;
    char color[8];
    int price;       
} Shoe;

// [open file]

Shoe* shoes = NULL; // list of Shoes
Shoe shoe; // temp for reading

for (i = 0; fscanf(file,"%s %i %s %i\n", shoe.name, &shoe.size, shoe.color, &shoe.price) == 4; i++)
{
    shoes = realloc(shoes, (i+1) * sizeof *shoes);
    if (!shoes) ReportOutOfMemoryAndDie();
    shoes[i] = shoe;
}

答案 2 :(得分:2)

您确定调试器是这么说的吗?我很惊讶它甚至编译......

你想:

struct shoes *item

如果你没有证明你的结构的typedef,你必须在每次引用时明确说“struct”。

第二点:

item=(struct shoes*)realloc(item...

不要从传递给它的realloc()分配相同的指针。如果重新分配失败,它将返回NULL,这可能会杀死你。您应该确保检查初始malloc()realloc()

的结果

第三点:

您需要将int的地址传递给fscanf()。

fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price));

答案 3 :(得分:1)

您的代码存在两个问题:

第一。结构:

你可以用两种方式定义你的结构, 你的方式:

struct shoe{    
 char name[8];
 int size;
 char color[8];
 int price;  
};

在这种情况下,您应该将指向它的指针称为:

struct shoe *item;

使用typedef和defenition的另一种(可能更方便?)方式:

typedef struct {    
 char name[8];
 int size;
 char color[8];
 int price;  
} shoe;

在这种情况下,您应该将指向它的指针称为:

shoe *item;

因此,您发布的代码不应该编译。

第二个:

在你展示的情况下,应该给fscanf指向整数/字符的指针。 你已经正确传递了char指针(因为你传递了一个char数组的名称,它实际上是一个指向第一个元素的char指针),但是你已经传递了一些整数,而fscanf需要指向它应该填充的整数的指针,所以你的代码应该是:

fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price));