我不知道如何解释这个,但这段代码可以完美编译但是当你运行它时,SIGSEV。 拜托,谁能准确说出我弄错了什么? 事实是我希望能够通过索引访问元素,如下所示,同时能够使用struct。
#include #include /* This is a struct describing properties of an element */ struct element{ int age; char* name; }; /* This struct contains a pointer to a pointer on a element "struct element" */ struct person{ struct element** p; int id; }; /* Thus function initializes a struct person by allocation memory for it */ struct person* init(int size) { struct person* sample = (struct person* )malloc(size*sizeof(struct person)); sample->p = NULL; sample->id = 0; return sample; } /* use this function to insert a new element in the struct */ void insert(struct person* sample, char* _name, int _age) { sample->p[sample->id]->name = _name; /* the program crashes here according to the debugger , but why?? */ sample->p[sample->id]->age = _age; /* of course, this will cause trouble too because it has the same construct as the previous one */ sample->id++; } /* main entry */ int main() { struct person* student = init(10); /* Allocating space for 10 students */ insert(student, "kido", 8); printf("Your name is %s and your age is %d", student->p[0]->name, student->p[0]->age); /* we can't write student->p->name */ return 0; }
问题出在您在问题中标记的代码行的insert
方法中
sample->p[sample->id]->name = _name;
您的程序中没有任何地方为person
结构内部的p
数组分配内存。 因此,此值始终为NULL
。 尝试分配此值将正确导致程序崩溃。
要解决此问题,您需要确保p
数组足够大,以容纳表达式sample->id
提供的索引。 实现此目的的最佳方法是使用realloc
函数并向person
添加字段以存储p
数组的大小
这是一个快速的样本。 注意:为了简单起见,省略了错误检查和0内存初始化。
struct person{ struct element** p; size_t length; int id; }; void insert(struct person* sample, char* _name, int _age) { if (sample->id >= sample->length) { sample->p = realloc(sample->p, sizeof(element*) * sample->id); } ... }
虽然名称和年龄总是通过sample->id
字段索引,但看起来确实很奇怪。 这表明它始终位于相同的位置,在这种情况下不需要数组。 你能详细说明它应该如何运作吗?
在init()函数中,设置sample->p = NULL
。 在insert()函数中,您尝试取消引用 – > p成员sample->p[sample->id]->name
。 由于您没有指向 – > p到任何存储,因此您无法取消引用它。
Starting program: /home/nathan/c/seg Program received signal SIGSEGV, Segmentation fault. 0x0000000000400597 in insert (sample=0x601010, _name=0x400730 "kido", _age=8) at seg.c:28 28 sample->p[sample->id]->name = _name; /* the program craches here according to the debugger , but why?? */ (gdb) backtrace #0 0x0000000000400597 in insert (sample=0x601010, _name=0x400730 "kido", _age=8) at seg.c:28 #1 0x0000000000400601 in main () at seg.c:38 (gdb) p sample->id $1 = 0 (gdb) p sample->p $2 = (struct element **) 0x0
sample->p
未正确初始化。 如果你查看init
,它确实被初始化为NULL
。 sample->p[anything]
因此取消引用空指针,从而导致段错误。
当你调用init()
函数时,你为许多person
结构分配内存,并将第一个结构的’p’指针设置为NULL。
然后你尝试写’p’指向的内存。 当然,这仍然是NULL。
鉴于您的意见,我不认为init()正在做您想要它做的事情。 它为人员结构数组分配空间,而不是具有“p”数组的人。 另外,为什么双指针?
重新检查你的设计:)我通常用白板,铅笔和纸做,用我的“物品”盒子和指针箭头。 它将澄清您的想法,并可能在他们达到代码之前向您显示错误。
struct person* init(int size) { struct person* sample = (struct person* )malloc(size*sizeof(struct person)); sample->p = NULL; // p is a pointer to a pointer which is initialized to NULL // So, it cannot be dereferenced with out pointing to a valid // memory location. // sample -> p = (struct person**) malloc( sizeof(struct *person) ); // sample[p] = (struct(person*)) malloc( sizeof(struct person) ); // struct** -> struct* -> struct sample->id = 0; return sample; }
现在,这两个陈述是有效的 –
sample->p[sample->id]->name = _name; sample->p[sample->id]->age = _age;
以上就是c/c++开发分享指向结构的指针让人头疼。 。相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/544778.html