繁体   English   中英

在这个微小的c程序中导致分段错误错误的原因是什么?

[英]What is causing the segmentation fault error in in this tiny c program?

我正在编写一个小程序来练习mallocsscanf库函数。 但不幸的是我得到了分段错误错误。 我用Google搜索并挣扎了好几个小时但没有结果。 有谁能引导我走出这个?

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

void print_array(int a[], int num_elements);

int main(void) {
    int m;    
    printf("How many numbers do you count: \n");  
    scanf("%d", &m);
    int *a = (int*)malloc(m * sizeof(int*));
    char buf[100];
    setbuf(stdin, NULL);
    if (fgets(buf, sizeof buf, stdin) != NULL) {
        char *p = buf;
        int n, index;
        while (sscanf(p, "%d %n", &a[index], &n) == 1 && index < m) {
            // do something with array[i]
            index++;  // Increment after success @BLUEPIXY
            p += n;
        }
        if (*p != '\0')
            printf("you are giving non-numbers, will be ignored");
    }

    print_array(a, m);
    free(a);
    return 0;
}

void print_array(int a[], int num_elements) {
    int i;
    for (i = 0; i < num_elements; i++) {
        printf("%d ", a[i]);
    }
}

你的malloc有问题。 替换int* a = (int*)malloc(m*sizeof(int*)); with int* a = (int *)malloc(m*sizeof(int)); 你很幸运, sizeof int小于int* ,否则你可能会遇到很多问题。

我无法重现错误,下次更好地给出输入文本,但调试segfault我依赖于gdb。

$ gcc -g prog.c -o prog

$ gdb prog

gdb> run [args]

这将打破导致段错误的程序。 使用本教程可获得更多知识。 gdb教程

您的程序有多个错误:

  • 你不检查scanf()的返回值。 无效的输入将导致m保持未初始化,分配m * sizeof(int)可能会失败。

  • malloc计算的大小不正确。 在C中不需要转换malloc()的返回值,并认为是坏的样式。 此外,您应该检查分配失败。 请改用:

     int *a = malloc(m * sizeof(int)); 
  • indexsscanf(p, "%d %n", &a[index], &n)中未初始化sscanf(p, "%d %n", &a[index], &n)肯定会导致未定义的行为,因为您告诉sscanf()int值存储到内存中的某个随机地址中。

  • 存储到&a[index] 之后测试index < m ,导致潜在的缓冲区溢出。 sscanf()前面交换测试。

这是一个修改版本:

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

void print_array(const int a[], int num_elements);

int main(void) {
    int m;    
    printf("How many numbers do you count:\n");  
    if (scanf("%d", &m) != 1 || m <= 0) {
        fprintf(stderr, "invalid input\n");
        return 1;
    }
    int *a = malloc(m * sizeof(int));
    if (a == NULL) {
        fprintf(stderr, "memory allocation failed\n");
        return 1;
    }
    char buf[100];
    setbuf(stdin, NULL);  // why do you want stdin to be unbuffered?
    if (fgets(buf, sizeof buf, stdin) != NULL) {
        char *p = buf;
        int n, index = 0;
        while (index < m && sscanf(p, "%d %n", &a[index], &n) == 1) {
            // do something with array[i]
            index++;  // Increment after success @BLUEPIXY
            p += n;
        }
        if (*p != '\0') {
            printf("you are giving non-numbers or extra input, will be ignored\n");
        }
    }

    print_array(a, m);
    free(a);
    return 0;
}

void print_array(const int a[], int num_elements) {
    for (int i = 0; i < num_elements; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

大多数[潜在]错误原因似乎来自未初始化自动变量:

scanf("%d",&m);

如果失败,则m具有未定义的值,因为您没有初始化它。

sscanf你使用&a[index]index尚未初始化,所以它可以写在任何地方。

另请参阅注释,以识别更多错误(例如,检查sscanf的返回值)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM