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;
}
这个程序 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;
}