C: sizeof struct of structs 查找结构中元素的数量
C: sizeof struct of structs to find number of elements in struct
我有两个结构:
struct point {
double x;
double y;
const char *description;
};
struct geomap {
struct point points[];
};
假设我在新地图中添加了 x 个点。我如何从 sizeof 开始得到那个数字 x?或者有没有其他方法可以知道我在新地图中添加了多少点?我需要一个循环来删除点并做其他事情,但我无法计算出元素的数量。
我试过了
sizeof(m->points[])/sizeof(m->points[0])
但它说:ERR expected expression
如果您想更快地玩一些代码:
static int counter = 0;
struct geomap *geomap_new() {
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap));
if (!a_geomap)
exit(0);
struct point *a_point = (struct point *)malloc(sizeof(point));
if (!a_point)
exit(0);
return a_geomap;
}
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
counter++;
if (!m) {
printf("failed to allocate new point");
return 0;
}
return 1;
}
int main() {
struct geomap *m = geomap_new();
geomap_add_point(m, 10324, 2341213.2, "212222");
geomap_add_point(m, 103212, 221341.2, "21wdd2");
geomap_add_point(m, 103241, 2.2, "2213122");
geomap_add_point(m, 1034123, 23341.2, "1111");
geomap_add_point(m, 1000324213, 23234242341.2, "dediowd");
return 1;
}
在此示例中,结构中始终有 0 个点。
尽管结构中有 0 个点,但您的代码写入了第 1、2、3、4 和 5 个点,从而覆盖了一些不属于您的内存。
所以用数字0
可以得到点数。
如果你想分配一个带有一些点的地图,你可以这样做:
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap) + NUMBER_OF_POINTS*sizeof(point));
如何存储由您决定NUMBER_OF_POINTS
。例如,您可以决定它始终为 10。或者您可以在 struct geomap
中添加另一个 int
来存储号码。
请注意,数组创建后无法调整大小。曾经。
首先,您应该考虑数组是否是用于此容器的正确数据类型。如果您打算经常 add/remove 项,那么链表或图可能更合适。
至于struct point points[];
,这是一个so-called 灵活数组成员。它只能放在结构的末尾,并且该结构需要在它旁边有其他成员。一个灵活的数组成员被认为是一个不完整类型的数组,所以你不能在它上面使用 sizeof
因为大小在 compile-time 是未知的。您必须手动跟踪尺寸。
正确的用法应该是这样的:
struct geomap {
size_t size;
struct point points[];
};
struct geomap *geomap_new(size_t def_size) {
struct geomap *obj = malloc( sizeof *obj + sizeof(struct point[def_size]) );
obj->size = def_size;
...
也就是你一次性给对象和灵活数组分配内存。
首先,这不是最小可重现的例子。
你有一些errors/typos。
错误 #1:
/* ... */
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap));
/* ... */
struct point *a_point = (struct point *)malloc(sizeof(point));
/* ... */
您在这里尝试在地理地图中分配点数组,对吗?参见 malloc(/*size in bytes*/)
。猜猜这段代码应该是这样的:
int i = 0;
/* ... */
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(struct geomap));
a_geomap->points = (struct point *)malloc(sizeof(struct point) * /* Maximum number of points here */ )
/* ... */
错误#2:
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
counter++;
if (!m) {
printf("failed to allocate new point");
return 0;
}
return 1;
}
如果您超出了数组的大小,您应该在此处检查。否则你可能会得到 SIGSEGV(分段错误)。应该是:
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
if (!m) {
printf("No geomap!!!");
return -1;
}
// Here check for size
if (counter >= /* Maximum number of points here */) {
printf("No space for new point!!!");
return -1;
}
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
++counter;
return 0;
}
最后...
警告 #1:
您应该考虑通常的做法,我们通常 return 从函数 负值 错误和 zero 成功。
P.S。简短的回答:如果你有一个静态数组,那么 count = (sizeof(/*array*/) / sizeof(/*element type*/))
应该可以工作。
但是!
这将更新动态数组。仅限动态数组 cound = /*Number of elements*/
.
示例:
/* For static array: */
#define MAX_ARR_T_DATA_SIZE 100
/* ... */
struct arr_t {
int data[MAX_ARR_T_DATA_SIZE];
};
/* ... */
arr_t array;
int count = sizeof(struct array) / sizeof(int);
/* For dynamic array: */
#define MAX_ARR_T_DATA_SIZE 100
/* ... */
struct arr_t {
int* data;
};
/* ... */
arr_t array;
array.data = (int*)malloc(sizeof(int) * MAX_ARR_T_DATA_SIZE);
int count = MAX_ARR_T_DATA_SIZE;
P.P.S。另外,我建议您阅读有关动态数组的内容。这例如:
http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/2-C-adv-data/dyn-array.html
我有两个结构:
struct point {
double x;
double y;
const char *description;
};
struct geomap {
struct point points[];
};
假设我在新地图中添加了 x 个点。我如何从 sizeof 开始得到那个数字 x?或者有没有其他方法可以知道我在新地图中添加了多少点?我需要一个循环来删除点并做其他事情,但我无法计算出元素的数量。
我试过了
sizeof(m->points[])/sizeof(m->points[0])
但它说:ERR expected expression 如果您想更快地玩一些代码:
static int counter = 0;
struct geomap *geomap_new() {
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap));
if (!a_geomap)
exit(0);
struct point *a_point = (struct point *)malloc(sizeof(point));
if (!a_point)
exit(0);
return a_geomap;
}
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
counter++;
if (!m) {
printf("failed to allocate new point");
return 0;
}
return 1;
}
int main() {
struct geomap *m = geomap_new();
geomap_add_point(m, 10324, 2341213.2, "212222");
geomap_add_point(m, 103212, 221341.2, "21wdd2");
geomap_add_point(m, 103241, 2.2, "2213122");
geomap_add_point(m, 1034123, 23341.2, "1111");
geomap_add_point(m, 1000324213, 23234242341.2, "dediowd");
return 1;
}
在此示例中,结构中始终有 0 个点。
尽管结构中有 0 个点,但您的代码写入了第 1、2、3、4 和 5 个点,从而覆盖了一些不属于您的内存。
所以用数字0
可以得到点数。
如果你想分配一个带有一些点的地图,你可以这样做:
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap) + NUMBER_OF_POINTS*sizeof(point));
如何存储由您决定NUMBER_OF_POINTS
。例如,您可以决定它始终为 10。或者您可以在 struct geomap
中添加另一个 int
来存储号码。
请注意,数组创建后无法调整大小。曾经。
首先,您应该考虑数组是否是用于此容器的正确数据类型。如果您打算经常 add/remove 项,那么链表或图可能更合适。
至于struct point points[];
,这是一个so-called 灵活数组成员。它只能放在结构的末尾,并且该结构需要在它旁边有其他成员。一个灵活的数组成员被认为是一个不完整类型的数组,所以你不能在它上面使用 sizeof
因为大小在 compile-time 是未知的。您必须手动跟踪尺寸。
正确的用法应该是这样的:
struct geomap {
size_t size;
struct point points[];
};
struct geomap *geomap_new(size_t def_size) {
struct geomap *obj = malloc( sizeof *obj + sizeof(struct point[def_size]) );
obj->size = def_size;
...
也就是你一次性给对象和灵活数组分配内存。
首先,这不是最小可重现的例子。
你有一些errors/typos。
错误 #1:
/* ... */
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap));
/* ... */
struct point *a_point = (struct point *)malloc(sizeof(point));
/* ... */
您在这里尝试在地理地图中分配点数组,对吗?参见 malloc(/*size in bytes*/)
。猜猜这段代码应该是这样的:
int i = 0;
/* ... */
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(struct geomap));
a_geomap->points = (struct point *)malloc(sizeof(struct point) * /* Maximum number of points here */ )
/* ... */
错误#2:
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
counter++;
if (!m) {
printf("failed to allocate new point");
return 0;
}
return 1;
}
如果您超出了数组的大小,您应该在此处检查。否则你可能会得到 SIGSEGV(分段错误)。应该是:
int geomap_add_point(struct geomap *m, double x, double y, const char *descr) {
if (!m) {
printf("No geomap!!!");
return -1;
}
// Here check for size
if (counter >= /* Maximum number of points here */) {
printf("No space for new point!!!");
return -1;
}
m->points[counter].x = x;
m->points[counter].y = y;
m->points[counter].description = descr;
++counter;
return 0;
}
最后...
警告 #1:
您应该考虑通常的做法,我们通常 return 从函数 负值 错误和 zero 成功。
P.S。简短的回答:如果你有一个静态数组,那么 count = (sizeof(/*array*/) / sizeof(/*element type*/))
应该可以工作。
但是!
这将更新动态数组。仅限动态数组 cound = /*Number of elements*/
.
示例:
/* For static array: */
#define MAX_ARR_T_DATA_SIZE 100
/* ... */
struct arr_t {
int data[MAX_ARR_T_DATA_SIZE];
};
/* ... */
arr_t array;
int count = sizeof(struct array) / sizeof(int);
/* For dynamic array: */
#define MAX_ARR_T_DATA_SIZE 100
/* ... */
struct arr_t {
int* data;
};
/* ... */
arr_t array;
array.data = (int*)malloc(sizeof(int) * MAX_ARR_T_DATA_SIZE);
int count = MAX_ARR_T_DATA_SIZE;
P.P.S。另外,我建议您阅读有关动态数组的内容。这例如: http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/2-C-adv-data/dyn-array.html