【问题标题】:Unexpected Segfault - What am I doing wrong意外的段错误 - 我做错了什么
【发布时间】:2014-06-21 04:33:38
【问题描述】:

我一直在试图打破我的 C 编程技能,但我遇到了一个我似乎无法弄清楚的错误。该程序读入由换行符分隔的整数列表。这一点发生在 read_integer_file 中......我通过那里的输入没有问题。当我将数据通过 out 传回 main 时,我遇到了问题。

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

int read_integer_file(char* filename, int* out)
{
    FILE* file;
    file = fopen(filename, "r");
    /* check if the file open was successful */
    if(file == NULL)
    {
        return 0;
    }

    int num_lines = 0;

    /* first check how many lines there are in the file */
    while(!feof(file))
    {
        fscanf(file, "%i\n");
        num_lines++;
    }

    /* seek to the beginning of the file*/
    rewind(file);

    out = malloc(sizeof(int)*num_lines);

    if(out == NULL)
        return 0;

    int inp = 0;
    int i = 0;
    while(!feof(file))
    {
        fscanf(file, "%i\n", &inp);
        out[i] = inp;
        printf("%i\n", out[i]); /* <---- Prints fine here! */

        i++;
    }

    return num_lines;
}

int main(int argc, char** argv)
{
    if(argc < 2)
    {
        printf("Not enough arguments!");
        return -1;
    }

    /* get the input filename from the command line */
    char* array_filename = argv[1];

    int* numbers = NULL;
    int number_count = read_integer_file(array_filename, numbers);

    for(int i = 0; i < number_count; i++)
    {
        /* Segfault HERE */
        printf("%i\n", numbers[i]);
    }
}

【问题讨论】:

  • 您确定要让函数的返回类型为int*吗?
  • @500-InternalServerError 我确定我没有!更正了,这不在我的代码中,这是我在搞乱其他东西时留下的。
  • 另外,C 不允许在 for (In the main) 中声明变量
  • 我知道,我在 GCC 中特意开启了 -std=c99 作为选项

标签: c segmentation-fault


【解决方案1】:

您没有为数字分配任何内存。目前它没有指向任何地方。当它返回到调用函数时,它仍然没有指向任何地方。传递一个指向函数的指针以在函数内分配它。

int read_integer_file(char* filename, int** out)
{
     ...
     *out = malloc(sizeof(int)*num_lines);
     ...

     int number_count = read_integer_file(array_filename, &numbers);

【讨论】:

  • 您能否更新您的代码以便我看到它。或者发布一个新问题?
  • 我会更新代码,因为显然 cmets 对于代码片段来说不够健壮:P
  • 你能试试吗(*out)[i]
  • 做到了。工作得很漂亮。我在 (*out)[i] 上错过了什么概念?我的猜测是我试图在 out[i] 上进行间接寻址,并通过添加括号,我在原始指针上使用了间接寻址?
  • 您错过了操作顺序指针在操作顺序上非常低。
【解决方案2】:

这是您的代码的工作版本。请记住,fscanf 只是按照您编写它的方式跳过 \n,所以它就像编写 fscanf(file, "%d");

如果你不放置一个变量来处理它读取的内容,编译器可能看不到它,但你可能会得到一个错误..

所以这里是代码:

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

int read_integer_file(char* filename, int **out)
{
    FILE* file;
    file = fopen(filename, "r");
    /* check if the file open was successful */
    if(file == NULL)
    {
        return 0;
    }

    int num_lines = 0;
    int garbi;
    char garbc;

    /* first check how many lines there are in the file */
    while(!feof(file))
    {
        fscanf(file, "%d", &garbi);
        fscanf(file, "%c", &garbc);
        if (garbc=='\n') ++num_lines;
    }

    /* seek to the beginning of the file*/
    rewind(file);

    int *nbr = malloc(sizeof(int)*num_lines);

    if(nbr == NULL)
        return 0;

    int i = 0;
    while(!feof(file))
    {
        fscanf(file, "%d", &nbr[i++]);
        fscanf(file, "%c", &garbc);
    }
    *out=nbr;

    return num_lines;
}

int main(int argc, char** argv)
{
    if(argc < 2)
    {
        printf("Not enough arguments!");
        return -1;
    }

    /* get the input filename from the command line */
    char* array_filename = argv[1];

    int *numbers = NULL;
    int number_count = read_integer_file(array_filename, &numbers);

    int i;
    for(i = 0; i < number_count; ++i)
        printf("%d\n", numbers[i]);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-07-04
    • 2019-10-24
    • 2013-11-25
    • 2021-03-05
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多