2011-02-03 6 views
0

Итак, у меня небольшая проблема. Я пытаюсь создать хеш-таблицу, но я все время получаю сообщение об ошибке «Возврат из несовместимого типа указателя». Я знаю, что это значит, но я не знаю, почему мой код не работает. Я ищу объяснение, почему мой код не работает. Почему он не распознает массив как указатель?Возвращение указателя на массив указателей на структуры

Я создаю массив указателей на структуры для хэш-таблицы. (Внешне прикован) (я знаю, что мой код, вероятно, действительно отстой> < Я все еще учусь!)

struct hashTBL { 

    char *userID; 
    char *password; 
    struct hashTBL *next; 
}; 

typedef struct hashTBL Tbl; 
typedef struct hashTBL* TblPTR; 

TblPTR createHashTBL(int size) 
{ 
    char *userID; 
    char *password; 
    int i; 

    TblPTR hashArray[size]; 

    FILE* fpData; 
    char *fileName = "encrypted.txt"; 

    fpData = openReadFile(fileName); 

    TblPTR T = NULL; 

    while((fscanf(fpData, "%s", userID)) != EOF) 
    { 
     fscanf(fpData, "%s", password); 
     i = hash(userID, size); 



     if(hashArray[i] != NULL) 
     { 
      TblPTR H = hashArray[i]; 

      while(H != NULL) 
      { 
       T = H; 
       H = H->next; 
      } 
      H = newPTR(userID, password, T); 
     } 
     else 
     { 
      hashArray[i] = newPTR(userID, password, T); 
     } 

    } 
    closeFile(fpData); 
    return &hashArray; 
} 



TblPTR newPTR(char *userID, char *password, TblPTR T) 
{ 

    TblPTR H = (TblPTR)malloc(sizeof(Tbl)); 
    if(T != NULL) T->next = H; 
    H->userID = userID; 
    H->password = password; 
    H->next = NULL; 

    return H; 
} 
+0

После быстрого просмотра код кажется действительным, хотя достаточно сложно обнаружить ошибки в коде, даже когда компиляторы _do_ сообщают вам, в какой строке он включен. На какой линии это не удается? – Neil

+1

Просьба представить образец кода, который максимально приближен к компиляции, или указать, где произошла ошибка. Я предполагаю, что 'TblPTR' является typedef для' Tbl * ', но вы не указали определение' Tbl'. –

+0

return statment «возврат из несовместимого типа указателя» «функция возвращает адрес локальной переменной» – Bri

ответ

4

У вас есть по крайней мере две проблемы.

Во-первых, ваша createHashTBL() функция определена для возврата TblPTR объект, и вы возвращаются указатель на массив из TblPTR объектов. Вы должны изменить тип функции в соответствии с типом возвращаемого значения, который вы пытаетесь, или вернуть правильный тип объекта.

Во-вторых, ваш hashArray назначен в стеке в функции createHashTBL(), что означает, что вы не можете вернуть указатель на него. Когда ваша функция вернется, она исчезнет. Вы должны попытаться выделить массив с помощью malloc() или иметь указатель на указатель на предварительно выделенный массив.

+0

Вы должны понимать: 'hashArray' - * выделение стека * внутри' createHashTBL'. –

+0

AH! :) Каким будет тип для возвращаемого указателя? Потому что я честно не знаю, как вы это сделаете. – Bri

+0

@larsmans: да, конечно, исправлено. :-) – payne

2

TblPTR hashArray[size]; создан в стеке и не может быть возвращен, поскольку ваша переменная будет уничтожена в конце вашей функции.

Вместо этого вы должны использовать malloc() или static TblPTR hashArray[size]; (не рекомендуется).

И это неправильно:

return &hashArray; 

Вы возвращаете указатель на свой массив: (TBLPTR *). Просто сделайте

return hashArray; 
0

Ошибка компилятора указывает на то, что это может быть и другая проблема, например, отсутствие typedef. Вы всегда должны копировать/вставлять сообщения об ошибках, чтобы мы могли их проверить, а также указать, в какой строке включена ошибка, в код, который вы вставляете, - это поможет каждому понять проблему.

Здесь есть некоторые ошибки.

TblPTR createHashTBL(int size) { 

... 
TblPTR hashArray[size]; 
.. 

return &hashArray; 
} 
  • Вы не можете вернуть указатель на локальную переменную - эта переменная ушла, когда функция возвращает
  • createHashTable объявляется вернуть TBLPTR, но вернуться и hashArray; имеет совершенно другой тип, это указатель на массив TblPTR.

Эта функция должна быть, вероятно,

TblPTR *createHashTBL(int size) { 

... 
TblPTR *hashArray = malloc(size * sizeof *hashArray); 
.. 

return hashArray; 
} 

(Не забудьте освободить() элементы и hashArray, когда вы сделали с ним)

0

У вас есть две основные проблемы:

  1. Тип выражения &hashArray: TblPTR (*)[size] (указатель к size -elemen t массив TblPTR), а не TblPTR; вот откуда приходит предупреждение о несоответствии типа. Однако ...

  2. hashArray является локальным для функции; как только функция завершается, hashArray больше не действителен, поэтому вы будете возвращать указатель на мусор.

VLA - это не тот инструмент, который можно использовать здесь. Я предлагаю сделать следующие изменения:

TblPTR *createHashArray(size)  // return a pointer to TblPTR 
{ 
    ... 
    TblPTR *hashArray = malloc(sizeof *hashArray * size); 
    if (hashArray) 
    { 
    // initialize hash array as you're currently doing 
    } 
    return hashArray; 
} 

Обратите внимание, что вам придется free() массив в какой-то момент в коде.