"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 malloced 指针。

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 ints。

分配的指针的范围保留在 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);

分别