Не видя того же значения целого числа после возвращения в основной класс - PullRequest
1 голос
/ 14 января 2020

Я работаю над некоторым скелетным кодом для реализации таблицы ha sh. В основном классе есть часть, которая проверяет наличие ключа в таблице. Он допускает дубликаты, поэтому он ожидает вернуть массив указанного размера, и если записи превышают этот размер, он вызывается снова с большим массивом. Моя проблема с указателем "num_results", который объявлен как раз перед.

  int num_values = 1;

  valType* values = malloc(1 * sizeof(valType));

  int* num_results = NULL;

  get(ht, key, values, num_values, num_results);
  printf("num_results: %d\n", (*num_results));
  if ((*num_results) > num_values) {
    values = realloc(values, (*num_results) * sizeof(valType));
    get(ht, 0, values, num_values, num_results);
  }

  for (int i = 0; i < (*num_results); i++) {
    printf("value of %d is %d \n", i, values[i]);
  }
  free(values);

Он объявляется равным нулю (предположительно потому, что если результатов нет, память не теряется?)

int get(hashtable* ht, keyType key, valType *values, int num_values, int* num_results) {
  int slot = key % sizeof(ht);

  struct node *entry = ht->entries[slot];

  if(entry == NULL){
    printf("There are no matching hashed keys");
    return -1;
  }

  // Allocate the num_results, as just a NULL pointer was passed  
  if((num_results = malloc(sizeof(int))) == NULL){
    return -1;
  }
  // Start it at 0 so that it cxan be incremented as we check
  (*num_results) = 0;


  printf("num_results: %d\n", (*num_results));

  int temp = num_values;
  while(entry != NULL){
    if(entry->key == key){
      ++(*num_results);
      if(temp != 0){
        values[num_values-temp] = entry->value;
        --temp;
      }
    }
    entry = entry->next;
  }
  printf("num_results: %d\n", (*num_results));

  return 0;
}

Это функция get, и как вы можете видите, я выделяю необходимую память, устанавливаю ее на 0, и она увеличивается, как и ожидалось. Вывод выглядит так:

num_results: 0
num_results: 2
num_results: 73896

Меня это смущает, так как ясно, что результат 2 взят из последней строки метода, а последняя распечатка приходит сразу после возврата к основному ... Что здесь происходит ? Почему значение меняется?

1 Ответ

2 голосов
/ 14 января 2020

Вы должны передать указатель num_results по ссылке. В противном случае функция имеет дело с копией указателя.

Например

int get(hashtable* ht, keyType key, valType *values, int num_values, int ** num_results) {
  // ...
  if(( *num_results = malloc(sizeof(int))) == NULL){
    return -1;
  }
  //…

Вызов функции будет выглядеть как

  get(ht, key, values, num_values, &num_results);

На самом деле я не вижу большой смысл объявлять переменную num_results как указатель и динамически выделять для нее память в функции. Я бы объявил его, по крайней мере, как имеющий тип unsigned int.

Например

unsigned int num_results = 0;

, и тогда функция get может выглядеть как

int get(hashtable* ht, keyType key, valType *values, int num_values, unsigned int *num_results) {
    //…
    *num_results = 0;
    //…

и вызываться как

  get(ht, key, values, num_values, &num_results);

Обратите внимание, что вместо

int slot = key % sizeof(ht);

кажется, что вы имеете в виду

int slot = key % sizeof( *ht);
...