我正在尝试使用用户的输入作为大小将内存动态分配给结构,但每次我这样做时都会出现错误。
我的结构如下:
#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 无济于事。它应该让用户输入一个数字,然后将空间分配给结构。但是,每次我尝试运行该程序时,都会出现一个错误。
局部变量
struct PHONE_RECORD *phonebook;
隐藏同名全局变量
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;
}
就您提供的信息而言,这可以解决您的段错误。
使用符号常量(
NAME_LEN
、BIRTHDAY_LEN
、PHONE_LEN
)代替魔法值(50、12、15)。
使用局部变量并传递他们操作所需的任何数据。这使您的代码更容易推理。
检查
scanf()
的返回值,否则你可能操作的是未初始化的数据。
喜欢使用变量而不是
sizeof()
的类型。它使类型更改更容易,重复代码更少。
在适当的时候优先使用无符号类型。
num_records < 0
是什么意思? 0 应该是一个有效的选择吗? malloc(0)
是实现定义的,所以我在下面不允许它。
在
menu()
函数中为您的电话簿分配空间是没有意义的。将其移至main()
。
不要从 malloc 投射
void *
。
(不固定)如果您不需要从
num_records
返回的 num_space()
值,则将返回类型更改为 void
。如果这样做,请将返回值分配给变量。
(不固定)考虑在
char *
中使用 struct phonebook
而不是浪费的固定大小的字符串。它通常意味着每个成员的分配,但使用strdup()
.相当容易
最小化您的代码,以便您了解我们对您的期望:
#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);
}