1

我是 C 的新手。我试图了解动态内存分配在结构和数组的情况下是如何工作的。所以例如我有一个类似的代码。

struct Person
{
    int id;
    char *name;
    char *place;
};

struct Database
{ 
    struct Person *data_rows;
};

我想为字符数组名称和位置动态分配内存..以及 struct data_rows 数组..将它们的大小作为输入..那么理想的分配顺序和正确的语法应该是什么?谢谢。

4

3 回答 3

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 并稍后填写它们,例如当您从文件中读取数据时,或者您计划执行的任何操作时。或者,如果您确信您的代码始终“知道”哪些字段已初始化,哪些字段未初始化,则您可以根本不在这里初始化它。

于 2012-07-08T11:59:57.150 回答
1

我强烈建议编写一个函数person_newperson_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);
}
于 2012-07-08T12:03:26.183 回答
0

最好的办法是将你的结构转换为类,以下也适用于结构......

您在 Database 和 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]只不过是 -> *(data_rows + i)将指针的地址移动 i 次,然后取消引用它!

于 2012-07-08T12:03:18.277 回答