Нет. Ваши типы не совпадают.
Вы пытаетесь выделить таблицу записей хэша (т.е. типа table[i]
является struct hash_entry
), таблица указателей к hash_entries (т.е. типа table[i]
является struct hash_entry *
), или что-то еще? Основываясь на том, как читается ваш код, я принимаю первый случай, но дайте мне знать, если это неправильно.
Предположим, что вы будете динамически выделять таблицу struct hash_entry
, ваше объявление таблицы в вызывающем должен быть
struct hash_entry *table; // 1 *, no array dimension
функции должны быть называется в
int result = maketable(&table, number_of_elements);
и определенной как
int maketable (struct hash_entry **table, size_t size)
{
int r = 0;
// sizeof **table == sizeof (struct hash_entry)
*table = malloc(sizeof **table * size);
// *ALWAYS* check the result of malloc()
if (*table)
{
size_t i;
for (i = 0; i < size; i++)
memset(&(*table)[i], 0, sizeof (*table)[i]);
r = 1;
}
return r;
}
Несколько вещей, чтобы указать. Прежде всего, не делайте результат malloc()
. С C89 вам не нужно, и бросок подавит диагностику, если вы забудете включить stdlib.h или иначе не имеете прототип для malloc()
в области. Во-вторых, вы можете использовать оператор sizeof
для объектов вместо типов. Это может помочь уменьшить некоторые головные боли обслуживания (то есть, если вы измените тип table
в списке параметров, вам не придется менять вызовы sizeof
вместе с ним).
Наконец, обратите внимание, что адрес таблицы передается функции; поскольку мы пытаемся записать значение указателя, мы должны передать указатель на этот указатель.
Если вы пытались создать таблицу указателей на struct hash_entry
, код в основном то же самое, только дополнительный уровень косвенности:
ваше объявление таблицы в вызывающему должен быть
struct hash_entry **table; // 2 *, no array dimension
функция должна быть называется, как
int result = maketable(&table, number_of_elements);
и определяется, как
int maketable (struct hash_entry ***table, size_t size)
{
int r = 0;
// sizeof **table == sizeof (struct hash_entry *)
*table = malloc(sizeof **table * size);
// *ALWAYS* check the result of malloc()
if (*table)
{
size_t i;
for (i = 0; i < size; i++)
(*table)[i] = NULL;
r = 1;
}
return r;
}
EDIT Была ошибка в maketable
примерах; table
необходимо разыменовать перед применением индекса, то есть (*table)[i]
. Мы применяем индекс к тому, что table
указывает на, а не на указатель таблицы.
Извините за путаницу.
Я не понимаю. Вы выделяете память на стек для переменной и затем перераспределяете что-то в функции? - Кроме того, 'table' является локальной переменной. Вы выделяете что-то и назначаете его «таблице», которая исчезнет, когда функция вернется, что приведет к утечке памяти. –
Проблема в том, что я тоже не совсем понимаю. Является ли мое объявление структуры hash_entry ** table [size] неявным распределением памяти для меня? В этом случае я все еще должен malloc для hash_entrys, когда я объявляю их, не так ли? –
Объявление выделяет память для массива с размером 'size' указателей на указатели типа' hash_entry' на стек. Он не выделяет память для местоположений, на которые будут ссылаться элементы массива. –