C - "Segmentation fault: 11" 运行程序

C - "Segmentation fault: 11" running program

这个程序 returns "Segmentation fault: 11" 当我运行它时。编译器 (GCC) 没有 return 任何错误或警告。

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

typedef struct {
  char day[3];
  char month[3];
  char year[5];
} DATA;

DATA *data;

int main()
{
  FILE *file;
  char line_buffer[BUFSIZ];

  if (!(file = fopen("file.dat", "rt")))
  { 
    printf ("Something went wrong while opening the file.\n");
  }
  else
  {
    int line_number = 0;

    while (fgets(line_buffer, sizeof(line_buffer), file))
    {
      ++line_number;

      if      (line_number == 1) { strncpy(data->day,   line_buffer, 2); }
      else if (line_number == 2) { strncpy(data->month, line_buffer, 2); }
      else if (line_number == 3) { strncpy(data->year,  line_buffer, 4); }
    }

    printf("Content: %s-%s-%s\n", data->day, data->month, data->year); 
  }
  return 0;
}

file.dat的内容是:

12
08
1990

我用 GDB 调试了它,这是结果:

(gdb) run
Starting program: /Users/macuser/Desktop/Primitiva/Proyecto/a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007fff949413a0 in _dispatch_queue_attrs () from /usr/lib/system/libdispatch.dylib

这是什么意思,我该怎么做才能解决这个问题?谢谢!

您忘记为您的结构分配内存

DATA *data = malloc(sizeof(DATA));

您应该在向指针写入内容之前为指针分配内存。

请注意,虽然使用 malloc 会起作用,但这对您来说是不必要的额外工作,因为您还必须稍后在不再需要使用 data 结构时调用 free .但是为此,您应该将变量设为 main().

的局部变量

这应该可以解决您的问题

typedef struct {
char day[3];
char month[3];
char year[5];
} DATA;

DATA data;
/*  ^ no star here, because you don't need a pointer in your particular case */

int main()
{
FILE *file;
char line_buffer[BUFSIZ];

if (!(file = fopen("file.dat", "rt")))
{
    printf ("Something went wrong while opening the file.\n");
}
else
{
    int line_number = 0;

    while (fgets(line_buffer, sizeof(line_buffer), file))
    {
    ++line_number;

    if      (line_number == 1) { strncpy(data.day,   line_buffer, 2); }
    else if (line_number == 2) { strncpy(data.month, line_buffer, 2); }
    else if (line_number == 3) { strncpy(data.year,  line_buffer, 4); }
    }

    printf("Content: %s-%s-%s\n", data.day, data.month, data.year);
}
return 0;
}

在这种特殊情况下,您不需要将 data 声明为指针,在您正确理解动态内存分配之前,最好不要声明 data ]变量不需要是全局的,可以在main()函数里面声明。

分段错误是由无效的指针解引用引起的,如果你想使用指针,那么你应该这样做

typedef struct {
char day[3];
char month[3];
char year[5];
} DATA;

int main()
{
FILE *file;
char line_buffer[BUFSIZ];
if (!(file = fopen("file.dat", "rt")))
{
    printf ("Something went wrong while opening the file.\n");
}
else
{
    int line_number = 0;
    DATA *data;

    /* 
     * here data is an invalid pointer, it points nowhere. 
     * to make it valid you need malloc
     */
    data = malloc(sizeof(*data));
    /* on failure, malloc returns NULL, for example when there is no more memory left in the system 
     * so one should check for the return value
     */
    if (data == NULL)
    {
        fclose(file);
        return -1;
    }
    /* now data is a valid pointer you can derefrence it */

    while (fgets(line_buffer, sizeof(line_buffer), file))
    {
    ++line_number;

    if      (line_number == 1) { strncpy(data->day,   line_buffer, 2); }
    else if (line_number == 2) { strncpy(data->month, line_buffer, 2); }
    else if (line_number == 3) { strncpy(data->year,  line_buffer, 4); }
    }

    printf("Content: %s-%s-%s\n", data->day, data->month, data->year);
    /* after you have finished using the pointer, call free */
    free(data);
}
return 0;
}