使用 malloc 为结构体分配空间

问题描述 投票:0回答:1

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

我的结构如下:

#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 variable-assignment
1个回答
0
投票
  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. 使用符号常量(

    NAME_LEN
    BIRTHDAY_LEN
    PHONE_LEN
    )代替魔法值(50、12、15)。

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

  3. 检查

    scanf()
    的返回值,否则你可能操作的是未初始化的数据。

  4. 喜欢使用变量而不是

    sizeof()
    的类型。它使类型更改更容易,重复代码更少。

  5. 在适当的时候优先使用无符号类型。

    num_records < 0
    是什么意思? 0 应该是一个有效的选择吗?
    malloc(0)
    是实现定义的,所以我在下面不允许它。

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

  7. 不要从 malloc 投射

    void *

  8. (不固定)如果您不需要从

    num_records
    返回的
    num_space()
    值,则将返回类型更改为
    void
    。如果这样做,请将返回值分配给变量。

  9. (不固定)考虑在

    char *
    中使用
    struct phonebook
    而不是浪费的固定大小的字符串。它通常意味着每个成员的分配,但使用
    strdup()
    .

    相当容易
  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);
}
© www.soinside.com 2019 - 2024. All rights reserved.