使用 malloc 的分段错误
segmentation fault using malloc
我是 C 的新手,所以问这个问题可能很愚蠢:
我这里要做的是将数据输入到一个结构指针数组中,然后打印出来。但是当 运行 进入插入函数时出现分段错误。
下面是我的代码
common.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct book * Book;
struct book{
int id;
char *name;
};
extern int b_insert(Book *b, int id, char *name);
extern int b_print(Book books[], int len);
insert.c
#include "common.h"
int b_insert(Book *b, int id, char *name){
Book p;
p = (Book)malloc(sizeof(struct book));
p->id = id;
strcpy(p->name, name);
*b = p;
printf("success insert book:\n");
printf("\tID: %d Name: %s\n", (*b)->id, (*b)->name);
return 0;
}
int b_print(Book books[], int len){
int i;
printf("Book List\n");
for(i=0; i<len; i++){
printf("books[%d] = ID: %d, Name: %s\n", i, books[i]->id, books[i]->name);
}
return 0;
}
main.c
#include "common.h"
#define MAX 2
int main(){
Book books[MAX];
Book *b=books;
int i;
int id;
char name[10];
for(i=0; i<MAX; i++){
printf("please input new books info\n");
printf("ID: ");
scanf("%d", &id);
printf("Name: ");
scanf("%s", name);
if(b_insert(b, id, name) == -1){
printf("fail to insert\n");
}
b++;
}
b_print(books, MAX);
return 0;
}
主要问题:
在使用
之前为p->name
分配内存
strcpy(p->name, name);
使用 malloc
:
p->name = malloc(10); //Or some other size
其他问题:
删除此处的强制转换:
p = (Book)malloc(sizeof(struct book));
为什么? Here is the answer
if(b_insert(b, id, name) == -1){
永远不会是真的。
- 查看
malloc
的结果,判断是否分配内存成功。
- 查看所有
scanf
的return值,看是否扫描数据成功。
为第二个scanf
添加一个长度修饰符以防止缓冲区溢出:
scanf("%9s", name); /* +1 for the NUL-terminator */
您没有为姓名分配 space:
int b_insert(Book *b, int id, char *name){
Book p;
p = malloc(sizeof(struct book));
if (p != NULL)
{
p->name = malloc(strlen(name)+1); // It allocates space where the input name will be copied.
if (p->name != NULL)
{
p->id = id;
strcpy(p->name, name);
*b = p;
printf("success insert book:\n");
printf("\tID: %d Name: %s\n", (*b)->id, (*b)->name);
}
else return -1; // No space to allocate string
}
else return -1; // No space to allocate struct
return 0;
}
如前所述,为p->name
分配space。您可能还应该使用不同的东西来阅读书名,或者使用指向 char 指针的指针的 scanf 格式 %ms,或者使用缓冲区的 %9s
,否则标题 "war or peace" 也会导致段错误.
这里你创建了一个静态变量,它的 space 是自动分配的。
Book p;
你可以在给指针赋值的时候手动分配一个space,这行不是指针而是静态变量。
p = (Book)malloc(sizeof(struct book));
此外,如果你想引用静态变量的属性,你应该使用“.”。而不是“->”。所以你有两个选择。创建一个指针并为该结构分配一个 space,然后您“->”或创建静态变量。
p->id = id;
我是 C 的新手,所以问这个问题可能很愚蠢:
我这里要做的是将数据输入到一个结构指针数组中,然后打印出来。但是当 运行 进入插入函数时出现分段错误。
下面是我的代码
common.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct book * Book;
struct book{
int id;
char *name;
};
extern int b_insert(Book *b, int id, char *name);
extern int b_print(Book books[], int len);
insert.c
#include "common.h"
int b_insert(Book *b, int id, char *name){
Book p;
p = (Book)malloc(sizeof(struct book));
p->id = id;
strcpy(p->name, name);
*b = p;
printf("success insert book:\n");
printf("\tID: %d Name: %s\n", (*b)->id, (*b)->name);
return 0;
}
int b_print(Book books[], int len){
int i;
printf("Book List\n");
for(i=0; i<len; i++){
printf("books[%d] = ID: %d, Name: %s\n", i, books[i]->id, books[i]->name);
}
return 0;
}
main.c
#include "common.h"
#define MAX 2
int main(){
Book books[MAX];
Book *b=books;
int i;
int id;
char name[10];
for(i=0; i<MAX; i++){
printf("please input new books info\n");
printf("ID: ");
scanf("%d", &id);
printf("Name: ");
scanf("%s", name);
if(b_insert(b, id, name) == -1){
printf("fail to insert\n");
}
b++;
}
b_print(books, MAX);
return 0;
}
主要问题:
在使用
之前为p->name
分配内存
strcpy(p->name, name);
使用 malloc
:
p->name = malloc(10); //Or some other size
其他问题:
删除此处的强制转换:
p = (Book)malloc(sizeof(struct book));
为什么? Here is the answer
if(b_insert(b, id, name) == -1){
永远不会是真的。- 查看
malloc
的结果,判断是否分配内存成功。 - 查看所有
scanf
的return值,看是否扫描数据成功。 为第二个
scanf
添加一个长度修饰符以防止缓冲区溢出:scanf("%9s", name); /* +1 for the NUL-terminator */
您没有为姓名分配 space:
int b_insert(Book *b, int id, char *name){
Book p;
p = malloc(sizeof(struct book));
if (p != NULL)
{
p->name = malloc(strlen(name)+1); // It allocates space where the input name will be copied.
if (p->name != NULL)
{
p->id = id;
strcpy(p->name, name);
*b = p;
printf("success insert book:\n");
printf("\tID: %d Name: %s\n", (*b)->id, (*b)->name);
}
else return -1; // No space to allocate string
}
else return -1; // No space to allocate struct
return 0;
}
如前所述,为p->name
分配space。您可能还应该使用不同的东西来阅读书名,或者使用指向 char 指针的指针的 scanf 格式 %ms,或者使用缓冲区的 %9s
,否则标题 "war or peace" 也会导致段错误.
这里你创建了一个静态变量,它的 space 是自动分配的。
Book p;
你可以在给指针赋值的时候手动分配一个space,这行不是指针而是静态变量。
p = (Book)malloc(sizeof(struct book));
此外,如果你想引用静态变量的属性,你应该使用“.”。而不是“->”。所以你有两个选择。创建一个指针并为该结构分配一个 space,然后您“->”或创建静态变量。
p->id = id;