"分段错误"访问动态分配的struct成员时

时间:2015-06-28 11:25:59

标签: c struct heap-memory

我已经开始研究一个实现名为" PhoneBook"的结构的程序。有两个成员:"长度"和" assignedSpace",类型" unsigned int"。结构是动态分配的。结构的两个成员分配在名为" InitializePhoneBook"的外部函数中。现在,当我尝试在" main"内打印结构的两个成员的值时功能我得到了一个"分段错误"错误。

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;
} 

跑步&#34; ./ a.out&#34;用&#34; gdb&#34;我明白了:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400621 in main () at ./main.c:12
12      printf("%u %u\n", phoneBook->length, phoneBook->allocatedSpace);

3 个答案:

答案 0 :(得分:7)

malloc中的InitializePhoneBook()

phoneBook = malloc(sizeof(struct PhoneBook) * 1);

它不会修改main中的指针,因为您指定的指针是本地函数。将指针传递给指针或重写函数返回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。

答案 1 :(得分:1)

malloced指针的范围保留在InitializePhoneBook函数内。

为此你必须将指针返回到main,所以将原型更改为:

struct PhoneBook *InitializePhoneBook(struct PhoneBook *);

并且上述函数的最后一个语句应该是:

return phoneBook;

并在主要内部以这种方式调用:

phoneBook=InitializePhoneBook(phoneBook);

答案 2 :(得分:1)

C是按值传递的。这意味着在调用函数时会复制参数。您的函数InitializePhoneBook()将复制未初始化的指针,将为该副本分配malloc()的返回值,然后在离开函数时忘记该值。您的来电者将继续使用未初始化的原件。

您的功能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;
}

主要的电话必须改变

struct PhoneBook *phoneBook = InitializePhoneBook();

struct PhoneBook *phoneBook;
InitializePhoneBook(&phoneBook);

分别