gpt4 book ai didi

c - 检测到堆栈粉碎 : running program with dinamically allocated array of structures

转载 作者:太空宇宙 更新时间:2023-11-04 03:22:58 25 4
gpt4 key购买 nike

我正在编写以下程序:

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

int main(void)
{
plane* planes=NULL;
int size=0;

readPlanes(&planes, &size);

free(planes);
planes=NULL;

return EXIT_SUCCESS;
}


void readPlanes(plane** planes, int* size)
{
char buffer[100]={'\0'};
int airplaneID, modeli;
float fuel;
char modelc;
int invent=0;
int rettest=0;
do{
printf("Enter the number of planes:\n");
fgets(buffer, 100, stdin);
rettest=sscanf(buffer, "%d", size);
if((*size)<=0)
{
printf("Invalid number of planes: enter a non negative number\n");
rettest=0;
}

}while(rettest!=1);

*planes=(plane*)calloc((*size), sizeof(plane*));

for(invent=0; invent<(*size); invent++)
{
planes[invent]=calloc(1, sizeof(plane));

do{
rettest=0;
printf("Enter the airplaneID:\n");
fgets(buffer, 100, stdin);
rettest=sscanf(buffer, "%d", &airplaneID);
if(airplaneID<0)
{
printf("Invalid airplaneID: enter a positive number\n");
rettest=0;
}

}while(rettest!=1);

planes[invent]->airplaneID=airplaneID;

do{
rettest=0;
printf("Enter the model:\n");
fgets(buffer, 100, stdin);
rettest=sscanf(buffer, "%c %d", &modelc, &modeli);
if(modeli<0 || modelc<'A' || modelc>'Z')
{
printf("Invalid model: enter an uppercase letter followed by a non negative number\n");
rettest=0;
}

}while(rettest!=2);

planes[invent]->planemodel.letter=modelc;
planes[invent]->planemodel.number=modeli;

do{
rettest=0;
printf("Enter the fuel:\n");
fgets(buffer, 100, stdin);
rettest=sscanf(buffer, "%f", &fuel);
if(fuel<0.0f)
{
printf("Invalid fuel: enter a non negative number\n");
rettest=0;
}

}while(rettest!=1);

planes[invent]->fuel=fuel;

}
}

头文件是:

#ifndef PLANES_H_INCLUDED
#define PLANES_H_INCLUDED

typedef struct
{
char letter;
int number;
}model;


typedef struct
{
int airplaneID;
model planemodel;
float fuel;
}plane;

void readPlanes(plane**, int*);
int lowestFuel(plane*, int);
void printID(plane*, int, char*);


#endif // PLANES_H_INCLUDED

无论如何,当我使用 planes=1 运行程序时,程序运行没有问题。但是,如果我尝试使用 2 个或更多平面运行它,则会出现以下错误(在程序结束时,用户输入所有平面的所有参数后):

检测到堆栈破坏:/home/user/Documents/program/bin/Debug/program 已终止中止(核心转储)

我不知道为什么会这样,也不知道我的问题在哪里。有人能帮我吗?

最佳答案

给定 planes 声明为 plane **,此分配不正确:

*planes=(plane*)calloc((*size), sizeof(plane*));

您正在分配内存,plane * 将指向该内存;由于您将内存视为数组的存储,因此数组的元素(例如 (*planes)[0])必须是 plane 类型。但是,您没有为 plane 类型的 *size 元素分配足够的空间;只够那么多指针

用于分配的一种好的形式根据分配分配的指针指定所需的大小;例如,

mytype *p;
p = calloc(n, sizeof (*p));

观察分配的大小是根据 p 指向的事物的大小来定义的,这几乎总是你想要的,无需硬编码 p 的类型。这不仅减少了错误的范围,而且在更改 p 的类型方面也很灵活。 (另请注意,在 C 中转换 malloc/calloc/realloc 的结果不仅没有必要,而且被许多人认为是糟糕的形式。 )

在你的例子中,你分配的指针是*planes,所以上面的形式将实现为

*planes = calloc(*size, sizeof(**planes));

但是,您似乎对双指针感到困惑。这样做的唯一原因是使 readPlanes() 能够修改其调用者的局部变量。它并不意味着需要多级分配。特别是,分配内存并在 *planes 中记录指向它的指针后,随后分配更多内存并将其分配给 planes[0] 毫无意义,< em>这是一回事。然而,尝试将任何东西分配给 planes[1] 更没有意义,因为在调用此函数时,planes 指向 main的指针 planes,因此 planes[1] 指向一个 plane* 过去,到...什么?它没有定义,因此您的程序表现出未定义的行为。那是你的堆栈粉碎。

事实上,您根本不需要循环中的分配——您已经(在第一次更正之后)分配了您需要的所有空间。因为您将指针分配给了 *planes,所以您需要通过该指针访问它;这意味着使用 (*planes)[n] 形式的表达式来引用 nth 平面。例如,

(*planes)[invent].airplaneID = airplaneID;

关于c - 检测到堆栈粉碎 : running program with dinamically allocated array of structures,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43720384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com