malloc一个struct指针数组

我有以下结构:

typedef struct _chess { int **array; int size; struct _chess *parent; } chess; 

我有:

 typedef struct _chess *Chess; 

现在,我想创建一个动态长度数组来存储指向struct结构的指针,所以我做了以下内容:

 Chess array [] = malloc(size * sizeof(Chess)); 

这给了我一个错误:初始化程序无效。

如果我放弃[]并执行此操作:

 Chess array = malloc(size * sizeof(Chess)); 

它编译没有错误,但当我尝试通过执行以下操作将此数组的元素设置为NULL:

 array[i]=NULL; 

我收到一个错误:从类型’void *’分配类型’struct _chess’时出现不兼容的类型

知道我做错了什么吗? 谢谢。

array是一个有点误导性的名字。 对于动态分配的指针数组, malloc将返回指向内存块的指针。 你需要使用Chess*而不是Chess[]来保存指向你的数组的指针。

 Chess *array = malloc(size * sizeof(Chess)); array[i] = NULL; 

也许后来:

 /* create new struct chess */ array[i] = malloc(sizeof(struct chess)); /* set up its members */ array[i]->size = 0; /* etc. */ 

这里有很多typedef 。 我个人反对“隐藏星号”,即typedef :将指针类型转换为看起来不像指针的东西。 在C中,指针非常重要并且真正影响代码, foofoo *之间存在很多差异。

我认为,许多答案也对此感到困惑。

你对Chess值数组的分配,这是指向chess类型值的指针(同样,一个我真的不能推荐的非常令人困惑的命名法)应该是这样的:

 Chess *array = malloc(n * sizeof *array); 

然后,您需要通过循环初始化实际实例:

 for(i = 0; i < n; ++i) array[i] = NULL; 

这假设你不想为实例分配任何内存,你只需要一个指针数组,所有指针最初都指向什么。

如果你想分配空间,最简单的forms是:

 for(i = 0; i < n; ++i) array[i] = malloc(sizeof *array[i]); 

了解sizeof使用方式是如何100%一致的,并且永远不会开始提及显式类型。 使用变量中固有的类型信息,让编译器担心哪种类型。 不要重复自己。

当然,上面对malloc()了不必要的大量调用; 根据使用模式,在计算所需的总大小之后,只需调用一次malloc()就可以完成上述所有操作。 然后你仍然需要通过并初始化array[i]指针指向大块,当然。

我同意上面的@maverik,我不想用typedef隐藏细节。 特别是在你想要了解发生了什么的时候。 我也更喜欢看一切而不是部分代码片段。 话虽如此,这里是一个malloc并且没有复杂的结构。

该代码使用ms visual studio泄漏检测器,因此您可以尝试潜在的泄漏。

 #include "stdafx.h" #include  #include "msc-lzw.h" #define _CRTDBG_MAP_ALLOC #include  #include  // 32-bit version int hash_fun(unsigned int key, int try_num, int max) { return (key + try_num) % max; // the hash fun returns a number bounded by the number of slots. } // this hash table has // key is int // value is char buffer struct key_value_pair { int key; // use this field as the key char *pValue; // use this field to store a variable length string }; struct hash_table { int max; int number_of_elements; struct key_value_pair **elements; // This is an array of pointers to mystruct objects }; int hash_insert(struct key_value_pair *data, struct hash_table *hash_table) { int try_num, hash; int max_number_of_retries = hash_table->max; if (hash_table->number_of_elements >= hash_table->max) { return 0; // FULL } for (try_num = 0; try_num < max_number_of_retries; try_num++) { hash = hash_fun(data->key, try_num, hash_table->max); if (NULL == hash_table->elements[hash]) { // an unallocated slot hash_table->elements[hash] = data; hash_table->number_of_elements++; return RC_OK; } } return RC_ERROR; } // returns the corresponding key value pair struct // If a value is not found, it returns null // // 32-bit version struct key_value_pair *hash_retrieve(unsigned int key, struct hash_table *hash_table) { unsigned int try_num, hash; unsigned int max_number_of_retries = hash_table->max; for (try_num = 0; try_num < max_number_of_retries; try_num++) { hash = hash_fun(key, try_num, hash_table->max); if (hash_table->elements[hash] == 0) { return NULL; // Nothing found } if (hash_table->elements[hash]->key == key) { return hash_table->elements[hash]; } } return NULL; } // Returns the number of keys in the dictionary // The list of keys in the dictionary is returned as a parameter. It will need to be freed afterwards int keys(struct hash_table *pHashTable, int **ppKeys) { int num_keys = 0; *ppKeys = (int *) malloc( pHashTable->number_of_elements * sizeof(int) ); for (int i = 0; i < pHashTable->max; i++) { if (NULL != pHashTable->elements[i]) { (*ppKeys)[num_keys] = pHashTable->elements[i]->key; num_keys++; } } return num_keys; } // The dictionary will need to be freed afterwards int allocate_the_dictionary(struct hash_table *pHashTable) { // Allocate the hash table slots pHashTable->elements = (struct key_value_pair **) malloc(pHashTable->max * sizeof(struct key_value_pair)); // allocate max number of key_value_pair entries for (int i = 0; i < pHashTable->max; i++) { pHashTable->elements[i] = NULL; } // alloc all the slots //struct key_value_pair *pa_slot; //for (int i = 0; i < pHashTable->max; i++) { // // all that he could see was babylon // pa_slot = (struct key_value_pair *) malloc(sizeof(struct key_value_pair)); // if (NULL == pa_slot) { // printf("alloc of slot failed\n"); // while (1); // } // pHashTable->elements[i] = pa_slot; // pHashTable->elements[i]->key = 0; //} return RC_OK; } // This will make a dictionary entry where // o key is an int // o value is a character buffer // // The buffer in the key_value_pair will need to be freed afterwards int make_dict_entry(int a_key, char * buffer, struct key_value_pair *pMyStruct) { // determine the len of the buffer assuming it is a string int len = strlen(buffer); // alloc the buffer to hold the string pMyStruct->pValue = (char *) malloc(len + 1); // add one for the null terminator byte if (NULL == pMyStruct->pValue) { printf("Failed to allocate the buffer for the dictionary string value."); return RC_ERROR; } strcpy(pMyStruct->pValue, buffer); pMyStruct->key = a_key; return RC_OK; } // Assumes the hash table has already been allocated. int add_key_val_pair_to_dict(struct hash_table *pHashTable, int key, char *pBuff) { int rc; struct key_value_pair *pKeyValuePair; if (NULL == pHashTable) { printf("Hash table is null.\n"); return RC_ERROR; } // Allocate the dictionary key value pair struct pKeyValuePair = (struct key_value_pair *) malloc(sizeof(struct key_value_pair)); if (NULL == pKeyValuePair) { printf("Failed to allocate key value pair struct.\n"); return RC_ERROR; } rc = make_dict_entry(key, pBuff, pKeyValuePair); // a_hash_table[1221] = "abba" if (RC_ERROR == rc) { printf("Failed to add buff to key value pair struct.\n"); return RC_ERROR; } rc = hash_insert(pKeyValuePair, pHashTable); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } return RC_OK; } void dump_hash_table(struct hash_table *pHashTable) { // Iterate the dictionary by keys char * pValue; struct key_value_pair *pMyStruct; int *pKeyList; int num_keys; printf("i\tKey\tValue\n"); printf("-----------------------------\n"); num_keys = keys(pHashTable, &pKeyList); for (int i = 0; i < num_keys; i++) { pMyStruct = hash_retrieve(pKeyList[i], pHashTable); pValue = pMyStruct->pValue; printf("%d\t%d\t%s\n", i, pKeyList[i], pValue); } // Free the key list free(pKeyList); } int main(int argc, char *argv[]) { int rc; int i; struct hash_table a_hash_table; a_hash_table.max = 20; // The dictionary can hold at most 20 entries. a_hash_table.number_of_elements = 0; // The intial dictionary has 0 entries. allocate_the_dictionary(&a_hash_table); rc = add_key_val_pair_to_dict(&a_hash_table, 1221, "abba"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } rc = add_key_val_pair_to_dict(&a_hash_table, 2211, "bbaa"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } rc = add_key_val_pair_to_dict(&a_hash_table, 1122, "aabb"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } rc = add_key_val_pair_to_dict(&a_hash_table, 2112, "baab"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } rc = add_key_val_pair_to_dict(&a_hash_table, 1212, "abab"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } rc = add_key_val_pair_to_dict(&a_hash_table, 2121, "baba"); if (RC_ERROR == rc) { printf("insert has failed!\n"); return RC_ERROR; } // Iterate the dictionary by keys dump_hash_table(&a_hash_table); // Free the individual slots for (i = 0; i < a_hash_table.max; i++) { // all that he could see was babylon if (NULL != a_hash_table.elements[i]) { free(a_hash_table.elements[i]->pValue); // free the buffer in the struct free(a_hash_table.elements[i]); // free the key_value_pair entry a_hash_table.elements[i] = NULL; } } // Free the overall dictionary free(a_hash_table.elements); _CrtDumpMemoryLeaks(); return 0; } 

恕我直言,这看起来更好:

 Chess *array = malloc(size * sizeof(Chess)); // array of pointers of size `size` for ( int i =0; i < SOME_VALUE; ++i ) { array[i] = (Chess) malloc(sizeof(Chess)); }