Использование malloc в C для выделения места для typedef'd типа - PullRequest
3 голосов
/ 23 ноября 2010

Я не совсем уверен, что именно мне нужно использовать в качестве аргумента для malloc для выделения пространства в функции table_allocate (int).Я думал просто count_table * cTable = malloc (sizeof (count_table *)), но это ничего не делает с параметром размера.Должен ли я также выделить место для list_node_t?Ниже то, с чем я работаю.

в файле .h мне дали эту подпись:

//create a count table struct and allocate space for it                         
//return it as a pointer                                                        
count_table_t* table_allocate(int);

Вот структуры, которые я должен использовать:

typedef struct list_node list_node_t;

struct list_node {
  char *key;
  int value;

  //the next node in the list                                                   
  list_node_t *next;
};

typedef struct count_table count_table_t;

struct count_table {
  int size;
  //an array of list_node pointers                                              
  list_node_t **list_array;
};

Спасибо!

Ответы [ 4 ]

7 голосов
/ 23 ноября 2010
<s>count_table* cTable = malloc(sizeof(count_table*))</s>

неправильно. Должно быть

count_table* cTable = malloc(sizeof(count_table));

Кроме того, вы также должны выделить память для list_node_t также отдельно.

EDIT:

Помимо того, что Клиффорд указал на выделение памяти для узла списка, я думаю, что распределение памяти также должно быть выполнено для char *key внутри узла списка.

2 голосов
/ 23 ноября 2010

Учитывая, что int является параметром "size" для созданного count_table_t, кажется, что вы должны как выделить сам count_table_t, так и инициализировать его члены.

Инициализация элемента list_array также включает выделение памяти, поэтому она будет выглядеть следующим образом:

count_table_t *table_allocate(int size)
{
    count_table_t *table = malloc(sizeof *table);
    int i;

    table->size = size;
    table->list_array = malloc(size * sizeof table->list_array[0]);
    for (i = 0; i < size; i++)
        table->list_array[i] = NULL;

    return table;
}

Однако вам также необходимо проверить наличие некоторых ошибок: умножение size на sizeof table->list_array[0] может переполниться, и любой из вызовов malloc() может завершиться ошибкой. Таким образом, функция должна выглядеть примерно так:

count_table_t *table_allocate(int size)
{
    count_table_t *table;
    int i;

    /* Check for overflow in list allocation size */
    if (size < 0 || size > (size_t)-1 / sizeof table->list_array[0])
        return NULL;

    table = malloc(sizeof *table);

    if (table == NULL)
        return NULL;

    table->size = size;
    table->list_array = malloc(size * sizeof table->list_array[0]);

    if (table->list_array == NULL) {
        free(table);
        return NULL;
    }

    for (i = 0; i < size; i++)
        table->list_array[i] = NULL;

    return table;
}

(Обратите внимание, что (size_t)-1 - это константа, равная максимальному значению size_t, которое является типом параметра для malloc()).

2 голосов
/ 23 ноября 2010

Ваше предложение: count_table* cTable = malloc(sizeof(count_table*)) выделит место только для указателя на count_table.

Тебе понадобится

count_table* cTable = malloc(sizeof(count_table) ) ;

Каждый узел списка будет выделен отдельно, а cTable-> size и cTable-> list_array и последний list_node_t::next обновлены соответственно. Сохранение указателя на последний добавленный узел ускорит добавление узлов.

Я не уверен, почему count_table::list_array имеет тип list_node_t**, а не просто list_node_t* (и также называется list_array, а не просто list). Вы хотите, чтобы это был и массив, и список одновременно? Это было бы несколько излишним. Член должен быть только указателем на первый узел, затем к последовательным узлам можно получить доступ через list_node::next

1 голос
/ 23 ноября 2010

В дополнение к другим постерам, которые указывают, что вы выделяете достаточно места только для указателя, а не места, которое займут требуемые данные, я настоятельно призываю вас сделать такие вещи:

Это поможет вам в случае, если тип cTable когда-либо изменится, вам не придется настраивать две части для этой линии, только тип.

...