【问题标题】:pointer segmentation fault at scanf [duplicate]scanf 处的指针分段错误 [重复]
【发布时间】:2015-11-11 22:53:51
【问题描述】:

一点帮助? 我很确定答案一定很愚蠢,但我不明白为什么我在 scanf 之后立即出现分段错误。我已经盯着我的一段代码很久了:

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

typedef struct Student{ 

    int grade, id; 
    struct Student *next; 
}student; 


student *initialize(){
    return NULL;
}

int main(){ 
    student *init; 
    student *nxt; 
    student *actual;
    int resp;

    init = (student*)malloc(sizeof(student)); 
    init = initialize();

    actual = init; 

    while(1){ 
        printf("type grade:\n"); 
        scanf("%d", &actual->grade); 
        printf("type id:\n"); 
        scanf("%d", &actual->id); 
        printf("wanna continue? (1-YES e <other>-NO)\n"); 
        if(resp==1){ 
            actual->next=(student*)malloc(sizeof(student)); 
            nxt=actual->next; 
        }else 
            break; 
    }

    actual->next=NULL;
    return 0; 
}

没什么大不了的,对吧?有一个结构,我想将一个值扫描到其中。在我的终端上,我得到:

type grade:
3
Segmentation fault (core dumped)

有什么想法吗?

【问题讨论】:

  • 改用scanf("%s", actual.grade)
  • 你在调用initialize时将init的值设置为NULL。
  • 为什么初始化后设置init为null,返回NULL...
  • 这里还有一个bug,使用scanf和回车...
  • 尝试使用 for() 循环,而不是 while()。它简化了生活!

标签: c pointers memory segmentation-fault


【解决方案1】:

首先你为init分配内存

init = (student*)malloc(sizeof(student)); 

但是您立即将init 设置为NULL,并在此处使用initialize() 函数的返回值

init = initialize();

这不仅是内存泄漏,而且您接下来在此处将actual 设置为 NULL

actual = init; 

然后在你的 while 循环中,你在几个地方取消引用 actual(它是 NULL),比如这里

scanf("%d", &actual->grade); 

取消引用 NULL 指针是未定义的行为,这可能是您的错误的来源。

【讨论】:

  • 谢谢!我看到你应该在教程中将你的结构初始化为空,我想我是按错误的顺序做的。新手对吗?哈哈我很抱歉这个愚蠢的问题,你们是最棒的!
  • 你应该知道很多'教程'都是废话。在用另一个有效值加载它之前将一个指针/任何东西归零是没有意义的,(无指针的?),充其量是,最坏的情况很容易出错。与 I/O 缓冲区的货物崇拜“bzero/memset”相同。
【解决方案2】:

您的 initialize() 函数返回 null 并且您正在创建内存泄漏。将数据成员初始化为合理的值,而不是返回 null。

【讨论】:

    【解决方案3】:

    “谢谢!我看到你应该在教程中将你的结构初始化为空,我想我是按错误的顺序做的.. 菜鸟对吗?哈哈我很抱歉这个愚蠢的问题,你们是最棒的"

    你是对的,你应该初始化为null。但是你的代码并没有这样做。

    你需要这样做

    student *initialize(student * st)
    {
       st->id = 0;
       st->grade = 0;
       st->next = NULL;
       return st;
    }
    

    或者使用 calloc 代替 malloc 来做一个学生对象(calloc 将内存清零)

    或者做

    init = malloc ...
    memset(init, 0, sizeof(student));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      相关资源
      最近更新 更多