我是C的新手。我正在尝试了解动态内存分配在结构和数组的情况下是如何工作的。例如,我有一个类似的代码..
struct Person
{
int id;
char *name;
char *place;
};
struct Database
{
struct Person *data_rows;
};
我想动态地为字符数组name和place..以及struct data_rows的数组分配内存。将它们的大小作为输入。那么理想情况下应该分配的顺序和相同的语法?感谢。
答案 0 :(得分:2)
嗯,“显然”你需要首先填写“struct Database”:
struct Database MyDatabase;
MyDatabase.data_rows=malloc(sizeof(MyDatabase.data_rows[0])*NumberOfPeople);
忽略我没有检查malloc()失败的事实,这将给你一个“struct Person”数组,全部未初始化。所以,很可能,你会想要初始化它们:
int i;
for (i=0; i<NumberOfPeople; i++)
{
struct Person* MyPerson;
MyPerson=&MyDatabase.data_rows[i];
MyPerson->id=i;
MyPerson->name=malloc(...);
/* Do something to store the name in MyPerson->name */
MyPerson->place=malloc(...);
/* Do something to store the place in MyPerson->name */
}
现在,这里的问题是我放在malloc上的“......”。如果你使用固定大小很容易,但是你可以宣布你的结构类似于
struct Person
{
int id;
char name[100];
char place[200];
};
基本上,我只是不知道名字的长度应该是多少,所以我只是输入“......”。
另外,我只是猜到了“id”可能是什么。使用数组索引实际上有点无意义: - )
当然,你现在不必全部完成。您可以设置名称并将指针置于NULL并稍后填充它们,例如当您从文件中读取数据时,或者您计划执行的任何操作时。或者你可以根本不在这里初始化它,如果你确信你的代码总是“知道”哪些字段被初始化而哪些不是。
答案 1 :(得分:1)
我强烈建议编写一个能够处理结构内存管理的函数person_new
和person_free
:
struct Person* person_new(char *name, char* place) {
struct Person* person = malloc(sizeof(struct Person));
person->name = strdup(name);
person->place = strdup(place);
return person;
}
void person_free(struct Person* person) {
free(person->name);
free(person->place);
free(person);
}
答案 2 :(得分:0)
最好的方法是将结构转换为类,以下也适用于结构...
您可以在Database和in Person中定义构造函数和析构函数,如下所示:
struct Person
{
Person(){
name = new char[256];
place = new char[256];
};
~Person(){
delete name;
delete place;
}
int id;
char *name;
char *place;
};
struct Database
{
Database(int nPersons){
data_rows = new Person[nPersons];
};
~Database(){
delete data_rows;
};
struct Person *data_rows;
};
或者你可以在没有构造函数和析构函数的情况下执行此操作,并在代码中按顺序分配所有内容,这是一种非常难看的方法!
为:
Database myData;
myData.data_rows = new Persons[40];
for(int i=0; i < 40; i++){
myData.data_rows[i].name = new char[256];
myData.data_rows[i].place = new char[256];
}
请注意,data_rows[i]
只不过是 - &gt; *(data_rows + i)
,它将指针的地址移动i次,然后取消引用它!