Могу ли я назначить Java-конструктор в c? - PullRequest
0 голосов
/ 27 января 2010

Я хочу «построить» (читай: malloc и memset) мою хеш-таблицу в c. Для этого я создал функцию следующим образом:

int maketable(struct hash_entry **table, int size){

    table = (struct hash_entry **)malloc(size*sizeof(struct hash_entry *));
    int i = 0;
    for (; i<size; i++) {
        memset(table[i], '\0', sizeof(struct hash_entry *));
    }
    return 0;

}

Учитывая, что таблица будет объявлена ​​как

struct hash_entry **table[size]

перед вводом этого кода я ничего не потеряю, когда вернусь из maketable, верно?

EDIT: Передает ли table в maketable(), что до тех пор, пока я изменю данные, на которые указывает table, изменения будут сохранены?

РЕДАКТИРОВАТЬ II: Я пытаюсь выделить массив указателей на указатели на hash_entries

Ответы [ 3 ]

4 голосов
/ 27 января 2010

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

Вне функции вы объявили таблицу как массив указателей на указатели структуры hash_entry - я предполагаю, что вы просто хотите, чтобы массив указателей структурировал элементы хеш-функции.

Если вы на самом деле объявляете table как массив, нет необходимости распределять это пространство по малому адресу. Вам просто нужен цикл, чтобы установить для каждого элемента значение NULL (не устанавливайте каждый элемент в нули).

Если цель состоит в том, чтобы выделить всю таблицу, это то, что вы ищете:

struct hash_entry **table;
...
int maketable(struct hash_entry ***table, int size){

    *table = malloc(size* sizeof **table);
    int i = 0;
    for (; i<size; i++) {
       (*table)[i] = NULL;
    }
    return 0;
}

Назовите это как

maketable(&table,100);

Я бы предпочел сделать так, чтобы таблица возвращалась так:

struct hash_entry ** maketable(int size){
   return calloc(size, sizeof(struct hash_entry *));
}

если объявление struct hash_entry **table[size] действительно то, что вам нужно, вы должны сообщить нам, что на самом деле должна делать ваша функция maketable () (например, хотите ли вы динамически размещаемый массив как один из элементов в этом стол?

2 голосов
/ 27 января 2010

Вам нужно будет присвоить результат malloc для * table - иначе он не будет виден вне функции.

Кроме того, типичным способом использования этого является объявление указателя на хеш-таблицу и передача адреса этого указателя в функцию.

1 голос
/ 27 января 2010

Нет.Ваши типы не совпадают.

Вы пытаетесь выделить таблицу записей хеша (т. Е. Тип 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 указывает на , а не к самому указателю таблицы.

Извините за путаницу.

...