"Segmentation fault" 访问动态分配的结构成员时
"Segmentation fault" when accesing dynamically allocated struct members
我已经开始编写一个程序,该程序实现了一个名为 "PhoneBook" 的结构,该结构具有两个成员:"length" 和 "allocatedSpace",类型均为 "unsigned int"。该结构是动态分配的。结构的两个成员在名为 "InitializePhoneBook" 的外部函数中分配。现在,当我尝试在 "main" 函数中打印结构的两个成员的值时,出现 "Segmentation fault" 错误。
PhoneBook.h
#ifndef PHONEBOOK_H
#define PHONEBOOK_H
struct PhoneBook
{
unsigned int length;
unsigned int allocatedSpace;
};
void InitializePhoneBook(struct PhoneBook *phoneBook);
void ClearPhoneBook(struct PhoneBook *phoneBook);
#endif
PhoneBook.c
#include <stdlib.h>
#include "PhoneBook.h"
void InitializePhoneBook(struct PhoneBook *phoneBook)
{
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
phoneBook->length = 0;
phoneBook->allocatedSpace = 1000;
}
void ClearPhoneBook(struct PhoneBook *phoneBook)
{
free(phoneBook);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "PhoneBook.h"
int main(void)
{
struct PhoneBook *phoneBook;
InitializePhoneBook(phoneBook);
printf("%d %d\n", phoneBook->length, phoneBook->allocatedSpace);
ClearPhoneBook(phoneBook);
return 0;
}
运行 "./a.out" 与 "gdb" 我得到:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400621 in main () at ./main.c:12
12 printf("%u %u\n", phoneBook->length, phoneBook->allocatedSpace);
当您在 InitializePhoneBook()
中执行 malloc
时:
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
它不会修改 main
中的指针,因为您分配的指针是函数的局部指针。将指针传递给指针或重写函数 return malloc
ed 指针。
void InitializePhoneBook(struct PhoneBook **phoneBook)
{
*phoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*phoneBook)->length = 0;
(*phoneBook)->allocatedSpace = 1000;
}
来电main()
:
InitializePhoneBook(&phoneBook);
并更改原型:
void InitializePhoneBook(struct PhoneBook **phoneBook);
我注意到的其他问题:
- 您还应该检查
malloc
的结果是否失败。
- 使用
%u
格式说明符打印 unsigned int
s。
分配的指针的范围保留在 InitializePhoneBook 函数内。
为此,您必须 return 指向 main 的指针,因此将原型更改为:
struct PhoneBook *InitializePhoneBook(struct PhoneBook *);
而上述函数的最后一条语句应该是:
return phoneBook;
在 main 中这样称呼它:
phoneBook=InitializePhoneBook(phoneBook);
C是按值传递。这意味着在调用函数时复制参数。您的函数 InitializePhoneBook()
将复制未初始化的指针,将分配给该副本 malloc()
的 return 值,然后在离开函数时忘记该值。您的来电者将继续使用未初始化的原始文件。
您的函数 InitializePhoneBook()
可以通过两种方式更改:
struct PhoneBook *InitializePhoneBook(void)
{
struct phoneBook *pb = malloc(sizeof(struct PhoneBook) * 1);
pb->length = 0;
pb->allocatedSpace = 1000;
return pb;
}
或
void InitializePhoneBook(struct PhoneBook **pPhoneBook)
{
*pPhoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*pPhoneBook)->length = 0;
(*pPhoneBook)->allocatedSpace = 1000;
}
必须更改 main 中的调用
struct PhoneBook *phoneBook = InitializePhoneBook();
或
struct PhoneBook *phoneBook;
InitializePhoneBook(&phoneBook);
分别
我已经开始编写一个程序,该程序实现了一个名为 "PhoneBook" 的结构,该结构具有两个成员:"length" 和 "allocatedSpace",类型均为 "unsigned int"。该结构是动态分配的。结构的两个成员在名为 "InitializePhoneBook" 的外部函数中分配。现在,当我尝试在 "main" 函数中打印结构的两个成员的值时,出现 "Segmentation fault" 错误。
PhoneBook.h
#ifndef PHONEBOOK_H
#define PHONEBOOK_H
struct PhoneBook
{
unsigned int length;
unsigned int allocatedSpace;
};
void InitializePhoneBook(struct PhoneBook *phoneBook);
void ClearPhoneBook(struct PhoneBook *phoneBook);
#endif
PhoneBook.c
#include <stdlib.h>
#include "PhoneBook.h"
void InitializePhoneBook(struct PhoneBook *phoneBook)
{
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
phoneBook->length = 0;
phoneBook->allocatedSpace = 1000;
}
void ClearPhoneBook(struct PhoneBook *phoneBook)
{
free(phoneBook);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "PhoneBook.h"
int main(void)
{
struct PhoneBook *phoneBook;
InitializePhoneBook(phoneBook);
printf("%d %d\n", phoneBook->length, phoneBook->allocatedSpace);
ClearPhoneBook(phoneBook);
return 0;
}
运行 "./a.out" 与 "gdb" 我得到:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400621 in main () at ./main.c:12
12 printf("%u %u\n", phoneBook->length, phoneBook->allocatedSpace);
当您在 InitializePhoneBook()
中执行 malloc
时:
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
它不会修改 main
中的指针,因为您分配的指针是函数的局部指针。将指针传递给指针或重写函数 return malloc
ed 指针。
void InitializePhoneBook(struct PhoneBook **phoneBook)
{
*phoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*phoneBook)->length = 0;
(*phoneBook)->allocatedSpace = 1000;
}
来电main()
:
InitializePhoneBook(&phoneBook);
并更改原型:
void InitializePhoneBook(struct PhoneBook **phoneBook);
我注意到的其他问题:
- 您还应该检查
malloc
的结果是否失败。 - 使用
%u
格式说明符打印unsigned int
s。
分配的指针的范围保留在 InitializePhoneBook 函数内。
为此,您必须 return 指向 main 的指针,因此将原型更改为:
struct PhoneBook *InitializePhoneBook(struct PhoneBook *);
而上述函数的最后一条语句应该是:
return phoneBook;
在 main 中这样称呼它:
phoneBook=InitializePhoneBook(phoneBook);
C是按值传递。这意味着在调用函数时复制参数。您的函数 InitializePhoneBook()
将复制未初始化的指针,将分配给该副本 malloc()
的 return 值,然后在离开函数时忘记该值。您的来电者将继续使用未初始化的原始文件。
您的函数 InitializePhoneBook()
可以通过两种方式更改:
struct PhoneBook *InitializePhoneBook(void)
{
struct phoneBook *pb = malloc(sizeof(struct PhoneBook) * 1);
pb->length = 0;
pb->allocatedSpace = 1000;
return pb;
}
或
void InitializePhoneBook(struct PhoneBook **pPhoneBook)
{
*pPhoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*pPhoneBook)->length = 0;
(*pPhoneBook)->allocatedSpace = 1000;
}
必须更改 main 中的调用
struct PhoneBook *phoneBook = InitializePhoneBook();
或
struct PhoneBook *phoneBook;
InitializePhoneBook(&phoneBook);
分别