我有一个类似的问题here关于在子功能中分配和初始化一个指向struct的问题。不幸的是,我无法扩展我在那里初始化数组结构的好解决方案。 第一个元素是OK,但第二个(以及所有后续元素)元素为零/ NULL。
这是一个评论的例子。也许有人可以帮助我...
#include <stdio.h>
#include <stdlib.h>
typedef struct {int n;} mystruct;
void alloc_and_init_array(mystruct **s)
{
// create an array containing two elements
*s = calloc(sizeof(mystruct), 2);
(*s[0]).n = 100;
(*s[1]).n = 200;
}
int main(void)
{
mystruct *s; // only a pointer. No memory allocation.
alloc_and_init_array(&s);
printf("1st element: %d\n", s[0].n); // here I get 100, that's OK
printf("2nd element: %d\n", s[1].n); // here I get 0. Why?
return 0;
}
答案 0 :(得分:2)
你需要一些括号:
((*s)[1]).n = 200;
^ extra parentheses required
下标([]
)的优先级高于间接(*
),因此如果没有括号,则首先应用它。
您需要取消引用s
以获取其指向的数组,然后访问索引1处的元素。
答案 1 :(得分:1)
在alloc_and_init_array
中,括号位于错误的位置。
s
是指向结构数组的指针。所以*s
是结构数组。因此(*s)[0]
和(*s)[1]
将分别为您提供该数组中的第一个和第二个结构。
所以这两行应该是:
(*s)[0].n = 100;
(*s)[1].n = 200;
答案 2 :(得分:1)
您正在调用未定义的行为,[]优先于*。你想要:
(*s)[0]).n = 100;
(*s)[1]).n = 200;
答案 3 :(得分:1)
作为明确的一般规则,为了避免跟随*
运算符的不可避免的优先级问题,我会这样做:
void alloc_and_init_array(mystruct **s)
{
mystruct *p;
// create an array containing two elements
p = calloc(sizeof(mystruct), 2);
if (p) {
// initialize it if creation succeeded.
p[0].n = 100;
p[1].n = 200;
}
*s = p;
}
我编写的一个细微差别是,如果对calloc()
的调用失败,我不会意外取消引用NULL指针。由于s
必须是非NULL,我很想把assert(s)
放在函数顶部附近来记录它并捕获不可能发生的错误。