我想迭代通过null终止的结构数组。 虽然循环工作正常,但当我尝试访问任何结构字段时,我得到“段错误”作为响应。我做错了什么?
PS我知道可以确定数组大小并使用简单的“for”构造。我只想弄清楚问题的根源。
PSS好的,如果数组初始化错误 - 如何正确执行?
#include <stdio.h>
#include <stdlib.h>
typedef struct demo
{
int a;
int b;
int c;
} demo;
demo * fieldDefinitions[] =
{
{ 1 , 1, 1 },
{ 2 , 2, 2 },
{ 3 , 3, 3 },
NULL
};
int main()
{
demo ** ptr = fieldDefinitions;
printf( "Array: %d \n", &fieldDefinitions );
while ( *ptr != NULL )
{
printf( "ptr: %d \n", ptr );
printf( "ptr: %d \n", (**ptr).a ); // <--- problem here
ptr++;
}
return 0;
}
答案 0 :(得分:6)
正如其他人已经指出的那样:听取你的编译器,一个符合标准的实现必须抱怨:
demo * fieldDefinitions[] =
{
{ 1 , 1, 1 }, // <-- note that this is not a pointer to a demo.
{ 2 , 2, 2 },
{ 3 , 3, 3 },
NULL
};
另外,使用p作为指针的printf
格式说明符,而不是d(用于整数类型)。
您需要指向demo
个对象,因此需要以某种方式创建这些对象,以便我们可以获取其地址。 C99添加了一个名为复合文字的功能(看起来有点类似于演员,但是,它们是不同的)创建未命名的对象:
#include <stdio.h>
#include <stdlib.h>
typedef struct demo
{
int a;
int b;
int c;
} demo;
demo * fieldDefinitions[] =
{
&(demo){ 1 , 1, 1 },
&(demo){ 2 , 2, 2 },
&(demo){ 3 , 3, 3 },
NULL
};
int main()
{
demo ** ptr = fieldDefinitions;
printf( "Array: %p \n", (void *)&fieldDefinitions );
for ( ; *ptr != NULL; ptr++ )
{
printf( "ptr: %p\n", (void *)ptr); // I'm not sure, what you really wanted ...
printf( "*ptr: %p\n", (void *)*ptr ); // ... but I think you meant this
printf( "ptr: %d\n", (*ptr)->a ); // or (**ptr).a, whatever you prefer
}
return 0;
}
通过复合文字创建的对象的生命周期是封闭块或静态的生命周期(如果在初始化程序中用于具有静态存储持续时间的标识符)(如本例所示)。
HTH
答案 1 :(得分:2)
demo * fieldDefinitions[ 4 ] =
{
{ 1 , 1, 1 },
{ 2 , 2, 2 },
{ 3 , 3, 3 },
NULL
};
你不能这样做,因为你做不到:
int *arr[] = {1, 2, 3, NULL};
向你发出警告:
initialization makes pointer from integer without a cast
如果你想使用指针运算,你可以这样做:
#include <stdio.h>
#include <stdlib.h>
typedef struct demo
{
int a;
int b;
int c;
} demo;
demo fieldDefinitions[] = {
{ 1 , 1, 1 },
{ 2 , 2, 2 },
{ 3 , 3, 3 },
};
int main(void)
{
demo *ptr = fieldDefinitions;
demo *end = &fieldDefinitions[sizeof(fieldDefinitions) / sizeof(fieldDefinitions[0]) - 1];
do {
printf( "ptr: %p \n", (void *)ptr);
printf( "ptr: %d \n", ptr->a);
} while (ptr++ < end);
return 0;
}
答案 2 :(得分:0)
demo * fieldDefinitions[] =
{
{ 1 , 1, 1 },
{ 2 , 2, 2 },
{ 3 , 3, 3 },
NULL
};
您声称 fieldDefinitions 将是一个演示对象指针数组,而是您自己提供对象。这是初始化结构数组的方式(最后除了NULL)。如果您的阵列是静态的,那么我建议创建具有已知大小的demo阵列,例如
unsigned const int fieldDefinitions_size = 3;
demo fieldDefinitions_arr[fieldDefinitions_size] = {
{1,1,1},
{2,2,2},
{3,3,3}
};
使用 fieldDefinitions_size 进行迭代。
或者如果你坚持使用演示指针数组,那么你可以为每个 demo 对象单独分配内存,并为 fieldDefinitions 数组分配地址。 This线程将非常有用。