Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用结构指针访问结构成员时出现Seg错误_C_Pointers_Structure - Fatal编程技术网

在C中使用结构指针访问结构成员时出现Seg错误

在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 ()

我的程序有什么问题,当我试图打印值时,我遇到seg错误

我的目标是在sample_函数中指定一些值

在main函数中,我想把这个结构复制到另一个结构中

#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          |