使用 malloc 为结构分配空间

Using malloc to allocate space to a struct

提问人:IMPNick 提问时间:4/1/2023 更新时间:4/1/2023 访问量:70

问:

我正在尝试使用用户的输入作为大小动态地将内存分配给结构体,但每次我这样做时,我都会得到一个段错误。

我的结构如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// structure that holds the info for a phone record
struct PHONE_RECORD {
    char name[50];
    char birthday[12];
    char phone[15];
} *phonebook;

动态分配它的代码如下:

int num_space(){
    int num_records;
    struct PHONE_RECORD *phonebook;
    printf("Enter num of records: ");
    scanf("%d", &num_records);
    phonebook = (struct PHONE_RECORD*) malloc(sizeof(struct PHONE_RECORD)*num_records);
    if (phonebook == NULL){ 
        printf("Not enough memory.\n");
        return 1;
    }
    free(phonebook);
    return num_records;
}

该代码允许用户输入一个数字,但随后给了我一个段错误并退出程序。这个项目还有其他部分,但我已经测试了它们,它们可以正常工作,只有 malloc 部分不起作用。 作为参考,这是我的主要:

#include <stdio.h>
#include <string.h>
#include "mini4Bphone.c"

extern void addRecord();
extern void findRecords();
extern void listRecords();
extern void loadCSV();
extern void saveCSV();
extern int num_space();

// dispaly the menu
void menu() {
    int choice;

    num_space();

    //display unitl user quits using while loop and execute whatever command user inputs 
    while (1) {
        printf("Phonebook Menu: ");
        printf("(1) Add ");
        printf("(2) Find ");
        printf("(3) List ");
        printf("(4) Quit ");
        printf("> ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            addRecord();
            break;
        case 2:
            findRecord();
            break;
        case 3:
            listRecords();
            break;
        case 4:
            return;
        default:
            printf("Invalid choice.\n");
            break;
        }
    }
}

// load tne csv,menu and save the csv after all wanted functions are complete, return 0
int main() {
    loadCSV();
    menu();
    saveCSV();
    return 0;
}

感谢您的任何意见,不胜感激!

我尝试在函数内部和外部使用 malloc 但无济于事。它应该让用户输入一个数字,然后将空间分配给结构体。但是,每次我尝试运行程序时,我都会收到一个段错误。

c struct malloc 变量赋值

评论

5赞 user253751 4/1/2023
我能问一下为什么你分配数组,然后立即取消分配它吗?
1赞 Barmar 4/1/2023
结构的声明也不应声明变量。
1赞 Barmar 4/1/2023
不要投射 malloc
3赞 Barmar 4/1/2023
num_space()未分配全局变量。它创建一个局部变量,为其分配内存,然后释放它。如果你的其他函数尝试使用全局变量,它仍然会是,你会得到一个分段错误。phonebookNULL
1赞 0___________ 4/1/2023
我们能知道你没有展示的功能是如何工作的吗?

答:

0赞 Allan Wind 4/1/2023 #1
  1. 局部变量隐藏同名的全局变量。struct PHONE_RECORD *phonebook;

  2. num_space()分配空间,然后释放空间。这是毫无意义的。大概你想为全局变量分配空间:

int num_space() {
    int num_records;
    printf("Enter num of records: ");
    scanf("%d", &num_records);
    phonebook = (struct PHONE_RECORD*) malloc(sizeof(struct PHONE_RECORD)*num_records);
    if (phonebook == NULL){ 
        printf("Not enough memory.\n");
        return 1;
    }
    return num_records;
}

就您提供的信息而言,这解决了您的段错误。

  1. 使用符号常量 (, , ) 而不是魔术值 (50, 12, 15)。NAME_LENBIRTHDAY_LENPHONE_LEN

  2. 使用局部变量并传递操作所需的任何数据。这使得你的代码更容易推理。

  3. 检查 的返回值,否则可能正在对未初始化的数据进行操作。scanf()

  4. 首选使用变量而不是类型。它使类型更改更容易,代码重复更少。sizeof()

  5. 在适当的时候,最好使用无符号类型。这是什么意思?0 是否应该是有效的选择? 是定义的实现,所以我在下面不允许它。num_records < 0malloc(0)

  6. 在名为 的函数中为电话簿分配空间是没有意义的。将其移至。menu()main()

  7. 不要从 malloc 强制转换。void *

  8. (不固定)如果不需要返回的值,请将返回类型更改为 。如果这样做,请将返回值分配给变量。num_recordsnum_space()void

  9. (不固定)考虑使用 in 而不是浪费的固定大小的字符串。这通常意味着为每个成员分配,但使用 .char *struct phonebookstrdup()

  10. 最小化您的代码,以便您知道我们对您的期望:

#include <stdio.h>
#include <stdlib.h>

#define NAME_LEN 50
#define BIRTHDAY_LEN 12
#define PHONE_LEN 15

struct phonebook {
    char name[NAME_LEN];
    char birthday[BIRTHDAY_LEN];
    char phone[PHONE_LEN];
};

size_t num_space(struct phonebook **phonebook) {
    size_t num_records;
    printf("Enter num of records: ");
    if(scanf("%zu", &num_records) != 1 || !num_records) {
        printf("scanf failed\n");
        return 0;
    }
    *phonebook = malloc(sizeof **phonebook * num_records);
    if (!*phonebook) {
        printf("malloc failed\n");
        return 0;
    }
    return num_records;
}

int main() {
    struct phonebook *phonebook = NULL;
    num_space(&phonebook);
    free(phonebook);
}