C:sizeof structs的structs,以查找结构中的元素数



我有两个结构:

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预期表达式如果你想更快地玩一些代码:

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;
}

首先,您应该考虑数组是否是用于此容器的正确数据类型。如果您计划经常添加/删除项目,那么链表或图形可能更合适。

对于struct point points[];,这是一个所谓的灵活阵列成员。它只能放在结构的末尾,结构旁边需要有其他成员。灵活的数组成员被视为不完整类型的数组,因此不能在它上使用sizeof,因为在编译时大小未知。你必须手动跟踪尺寸。

正确的用法是这样的:

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;
...

也就是说,一次性为对象和灵活的数组分配内存。

首先,这不是一个最小的可复制示例。

你有一些错误/打字错误。

错误#1:

/* ... */
struct geomap *a_geomap = (struct geomap *)malloc(sizeof(geomap));
/* ... */
struct point *a_point = (struct point *)malloc(sizeof(point));
/* ... */

在这里,你试图在geomap中分配点的数组,对吧?参见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:

您应该考虑常见的做法,通常我们在出错时从函数返回负值,在成功时返回零值。

附言:简短的回答:如果你有一个静态数组,那么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;

附言:我还建议你读一读关于动态数组的书。例如:http://www.mathcs.emory.edu/~张/课程/255/教学大纲/2-C-adv-data/dyn-array.html

在这个例子中,结构中总是有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来存储该号码。

请注意,数组在创建后无法调整大小。曾经

最新更新