在C中使用结构指针访问结构成员时出现Seg错误
我的程序有什么问题,当我试图打印值时,我遇到seg错误 我的目标是在sample_函数中指定一些值 在main函数中,我想把这个结构复制到另一个结构中在C中使用结构指针访问结构成员时出现Seg错误,c,pointers,structure,C,Pointers,Structure,我的程序有什么问题,当我试图打印值时,我遇到seg错误 我的目标是在sample_函数中指定一些值 在main函数中,我想把这个结构复制到另一个结构中 #include<stdio.h> #include<string.h> typedef struct { char *name; char *class; char *rollno; } test; test * sample_function ()
#include<stdio.h>
#include<string.h>
typedef struct
{
char *name;
char *class;
char *rollno;
} test;
test *
sample_function ()
{
test *abc;
abc = (test *)malloc(sizeof(test));
strcpy(abc->name,"Microsoft");
abc->class = "MD5";
abc->rollno = "12345";
printf("%s %s %s\n",abc->name,abc->class,abc->rollno);
return abc;
}
int main(){
test *digest_abc = NULL;
test *abc = NULL;
abc = sample_function();
digest_abc = abc;
printf(" %s %s %s \n",digest_abc->name,digest_abc->class,digest_abc->rollno);
return 1;
}
#包括
#包括
类型定义结构
{
字符*名称;
字符*类;
char*rollno;
}试验;
试验*
样本函数()
{
测试*abc;
abc=(测试*)malloc(测试规模);
strcpy(abc->name,“微软”);
abc->class=“MD5”;
abc->rollno=“12345”;
printf(“%s%s%s\n”,abc->name,abc->class,abc->rollno);
返回abc;
}
int main(){
test*digest_abc=NULL;
test*abc=NULL;
abc=样本_函数();
摘要abc=abc;
printf(“%s%s%s\n”,摘要\u abc->name,摘要\u abc->class,摘要\u abc->rollno);
返回1;
}
指针对我来说一直是一个噩梦,我从来没有理解过它。在
sample\u函数
中,您将abc
声明为指向test
结构的指针,但从未初始化它。它只是指向某个地方的杂草。然后你尝试去引用它来存储值-砰
你的程序根本不需要任何指针;结构可以通过C中的值进行传递
如果您确实希望保留与现在类似的接口,则必须添加一些动态分配(malloc
/free
调用),以确保实际分配了结构,并且指针实际指向它们
test * sample_function ()
{
test *abc;
strcpy(abc->name,"Surya");
你认为abc在这里指向什么?答案是,它并没有真正指向任何东西。您需要将其初始化为某个值,在本例中,这意味着分配一些内存
那么,让我们解决第一个问题:
test * sample_function ()
{
test *abc = malloc(sizeof(*abc));
strcpy(abc->name,"Surya");
现在,abc
指向某个东西,我们可以在那里存储东西
但是abc->name
也是一个指针,你认为它指向什么?同样,它并没有真正指向任何东西,当然也不能假设它指向可以存储字符串的地方
那么,让我们来解决第二个问题:
test * sample_function ()
{
test *abc = malloc(sizeof(*abc));
abc->name = strdup("Surya");
/* ... the rest is ok ... */
return abc;
}
现在,还有最后一个问题:您永远不会释放刚刚分配的内存(这可能不是问题,但在全尺寸程序中可能是一个bug)
所以,在main的末尾,你应该有
free(abc->name);
free(abc);
return 1;
}
最后一个问题是设计问题:您的结构中有三个指针,并且只有一个约定可以帮助您记住哪些指针是动态分配的(并且必须被释放),哪些指针指向字符串文本(并且不能被释放) 那很好,只要这个惯例在任何地方都得到遵守。一旦您动态分配
类
或rollno
,您就会出现内存泄漏。只要将name
指向字符串文字,就会发生崩溃和/或堆损坏
正如japreiss在评论中指出的那样,执行约定的一个好方法是编写专用函数,如:
void initialize_test(test *obj, const char *name, char *class, char *rollno) {
obj->name = strdup(name);
...
}
void destroy_test(test *obj) {
free(obj->name);
}
test *malloc_test(const char *name, ...) {
test *obj = malloc(sizeof(*obj));
initialize_test(obj, name, ...);
return test;
}
void free_test(test *obj) {
destroy_test(obj);
free(obj);
}
在函数
sample\u函数中
返回指向abc
的指针。由于组织方式的原因,在C中无法执行此操作
激活记录是包含函数调用、参数、返回地址、局部变量地址等所有相关信息的数据结构
当您调用一个函数时,一个新的激活记录被推到堆栈上,它可能看起来像这样
// Record for some function f(a, b)
| local variable 1 | <- stack pointer (abc in your case)
| local variable 2 |
| old stack pointer | <- base pointer
| return address |
| parameter 1 |
| parameter 2 |
---------------------
| caller activation |
| record |
//某些函数f(a,b)的记录
|局部变量1 |您没有为abc
=>未定义的行为分配内存。您不需要在C程序中强制转换malloc
的返回值。为什么您只对name使用strcpy,而不对class和rollno使用strcpy?他也没有为字符串分配任何内存。是的,这是真的。不过,这只对其中一个重要。我已经尝试过通过malloc分配内存,但仍然会点击seg fault-code edited恭喜,当我将第二个bug编辑到我的答案中时,你碰到了它:)这就解决了,谢谢,最后一个问题是,如果我释放了分配给abc的内存,但仍然希望在摘要\u abc中存储值,我该如何做+1这种结构的嵌套内存分配是常见的,最好将其封装在一个“构造函数”函数中,如void initialize\u test(test*the\u test,char*name,char*class,char*rollno)
负责所有分配和复制,以及无效清除测试(test*obj)
以释放内存。指针test*abc
按值返回。abc
的地址,这将是一个测试**
,并且确实超出了范围,没有出现在我能看到的任何地方。@无用的,我认为这是一个非常常见的术语,但也可以使用堆栈框架。我在您回复之前查找并编辑了该注释-它只是不熟悉:)嗯,我仍然认为abc公司的地址是一个骗人的东西——abc公司的地址从来没有被占用过。@这不是被退回的吗?我只是重读了我写的东西,我的意思是说指向abc的指针的地址;不是abc本身
// popped record
| local variable 1 | <- address of abc #
| local variable 2 | #
| old stack pointer | # Unallocated memory, any new function
| return address | # call could overwrite this
| parameter 1 | #
| parameter 2 | #
--------------------- <- stack pointer
| caller activation |
| record |