我有以下代码:
//length, width, height
typedef struct {
float L, W, H;
} TDim;
//contains details for each geometrical form
typedef struct {
char *id; // each geometrical form has a unique id
float volume;
TDim *dim;
} TForm;
TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));
return F;
}
这是在更多结构中操纵变量和指针的一个很好的练习。
我想要做的是存储id(基本上是字母'F'后跟1,2,3 ...),长度,宽度和高度的某个矩形长方体以计算其体积。 / p>
我需要对->
vs .
的使用情况进行一些解释
我了解->
使用地址,.
使用会员。
在int main()
中,我有:
F[0].id = "F1"; //the first cuboid has the id "F1"
F[0].dim[0].L = 1; //the first cuboid has length = 11
//could have used F[0].dim->L = 1; as well?
F[0].dim[0].W = 2;
F[0].dim[0].H = 3;
F[1].id = "F2"; //the second cuboid has the id "F2"
F[1].dim[1].L = 4; //this is where it breaks down - SEG_FAULT (I've used gdb to catch it)
导致该行中的SEG_FAULT的原因是什么?
答案 0 :(得分:2)
在此功能中:
TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));
return F;
}
您创建MAX
个TForm
元素的动态数组,但之后只为第一个id
和dim
成员分配内存,因此会出现段错误你试图在第二个元素中存储内存。
你需要这样的东西:
TForm* FormAlloc(void)
{
TForm *F = malloc(MAX * sizeof(TForm));
if ( !F ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
for ( size_t i = 0; i < MAX; ++i ) {
if ( (F[i].id = malloc(MAX)) == NULL ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
if ( (F[i].dim = malloc(MAX * sizeof(TDim))) == NULL ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
}
return F;
}
最有可能的情况是,您不希望将MAX
用于所有这三个目的,也就是说,您需要与TForm
完全相同数量的元素,因为每个id
都需要字符malloc()
1}}字符串可能很低。
其他更多小问题:
NULL
可以返回F[0].id = "F1";
,您应该检查一下。
在您问题的代码中,strcpy(F[0].id, "F1");
应为malloc()
或类似,否则您将失去对malloc()
编辑的内存的引用。< / p>
您不需要也不应该在C中投出sizeof(char)
的回报。
1
始终为F[0].dim[0].L = 1;
,因此您可以将其排除在外。
对于你评论中的问题:
这两个是等价的,在这里。使用下标运算符
F[0].dim->L = 1;
vsdim[0]
怎么样?
dim
会自动为您解除引用.
,因此您可以使用dim[n]
运算符来获取元素(*(dim + n)
等效于{{1}在C)。如果没有[0]
,dim
是一个直指针,那么您将使用->
运算符。显然,当您想要访问数组中的其他元素时,第一个表单会更方便。对于其他人,您必须将F[0].dim[1].L = 1;
替换为(F[0].dim + 1)->L = 1;
或类似内容,才能使用->
运算符,这会导致不必要的错综复杂。