2014-12-07 2 views
0

Я использую функцию таНос и инициализирует некоторую память для хэш-функции, например:Возвращаясь указатель на структуру malloc'ed в функции

int main (int argc, char * argv []) 
{ 
    Bucket * hashTable; 
    hashTable = createHashTable(); 
    ... 

в «main.c»

функция вызывается в другом файле заключается в следующем:

Bucket * createHashTable() 
{ 
    Bucket * hashTable = malloc (sizeof(Bucket) * HASHSIZE); 
    int c=0; 
    for (c=0;c<HASHSIZE;c++) 
    { 
    hashTable[c].key=NULL; 
    hashTable[c].text=NULL; 
    hashTable[c].next=NULL; 
    } 
    return hashTable; 
} 

Моя программа компилируется с «-pedantic -Wall», но ошибки сегментации. Использование GDB, я получаю это:

Reading symbols from hash...done. 
(gdb) break 11 
Breakpoint 1 at 0x400990: file main.c, line 11. 
(gdb) run 
Starting program: /home/user/Projects/random/hash 

Breakpoint 1, main (argc=1, argv=0x7fffffffdf78) at main.c:11 
11 hashTable = createHashTable(); 
(gdb) print hashTable 
$1 = (Bucket *) 0x400520 <_start> 
(gdb) print * hashTable 
$2 = { 
key = 0x89485ed18949ed31 <error: Cannot access memory at address 0x89485ed18949ed31>, 
text = 0x495450f0e48348e2 <error: Cannot access memory at address 
0x495450f0e48348e2>, next = 0xc74800400a90c0c7} 
(gdb) 

Часть заголовка с «ковшом» определение: структура

typedef struct bucket{ 
    char * key; 
    char * text; 
    struct bucket * next; 
} Bucket; 

Является ли это проблемой сфера? Когда функция закончена, она убивает мою память malloc'а или что?

Платформа - это 64-разрядная Linux, а адрес, возвращенный из malloc(), на этот раз был 0x1665010 - я предполагаю, что если бы это было неудачно, это было бы NULL.

EDIT: Следующая функция после этого, в main.c, пытается добавить запись в таблицу:

printf("Adding banana...\n"); 
addItem("Banana", "Bananas are yellow", &hashTable); 

(да, да - бананы, я знаю) функция является:

void addItem(char * key, char * data, Bucket ** table) 
{ 
    unsigned int hashkey; 
    hashkey=hash(key); 
    printf("%lu\n",strlen(key)); 
if (!table[hashkey]->text) /* SEGFAULTS HERE */ 
{ 
    table[hashkey]->key=key; 
    table[hashkey]->text=data; 
} 
else 
{ 
    Bucket * newListElement = malloc(sizeof(Bucket)); 
    newListElement->key=key; 
    newListElement->text=data; 
    newListElement->next = NULL; 
    table[hashkey]->next = newListElement; 
} 

}

+0

Это кажется действительным. На какой платформе вы работаете? Является ли 'malloc' возвращающим действительный адрес или сбой (возвращающий NULL)? – slugonamission

+0

Чтобы помочь вам проверить это, вы должны предоставить полный минимальный пример. Например, какие файлы заголовков вы включаете? Каково определение «Ведро»? и т. д. – glglgl

+0

Подождите, вы уверены, что это сбой на этой линии? Ваша команда 'break 11' для GCC сломает * до *, строка будет выполнена. – slugonamission

ответ

1

Эта линия:

if (!table[hashkey]->text) 

должно быть:

if (!(*table)[hashkey]->text) 

и точно так же на следующих строках. В этой функции table фактически является указателем на переменную, называемую hashTable, в main.

Другой способ исправить эту ошибку состоит в том, чтобы сделать функцию Bucket *, а не передавать адрес hashTable. Кажется, нет никакой потребности в функции знать адрес hashTable, поскольку он помещает только вещи в таблицу.

+0

Это сработало, это здорово Спасибо! Разве это не означает, что он передается по значению, хотя, следовательно, обновления в таблице не будут проходить через область функций? – Andomonir

+1

Вы не обновляете «таблицу» в любом месте функции (если только нет кода, который вы не опубликовали). Не путайте «таблицу» с тем, на что указывает «таблица». –

0

Я попытался воспроизвести эту проблему, но не смог добиться успеха.

Так что я только предполагаю, что вы, возможно, не указали правильную сигнатуру функции на свой основной модуль, и там она называется int createHashTable(). Это должно привести к предупреждению и приведет к потере верхних 32 бит вашего результирующего указателя IFF, у вас есть 64-битные указатели И 32 бит int.

Смежные вопросы