我正在尝试从控制台获取输入并将其添加到哈希表。 但是我得到了分段错误11。 所以,我使用gdb-apple调试了程序。 它显示我尝试访问内存我不能,使用指针变量。 我认为这是显而易见的,但我错过了它
这就是gdb正在显示的内容
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000986 in CreateHashTable (size=200) at hashing.c:29
29 h->Table[i]->next = NULL;
这是代码
标题文件:
#define LOAD_FACTOR 20
#define INITIAL_SIZE 200
struct HashTable *CreateHashTable(int size);
int HashSearch(struct HashTable *h,int data);
int HashInsert(struct HashTable *h,int data);
int HashDelete(struct HashTable *h, int data);
void Rehash(struct HashTable *h);
int Hash(int data, int size);
struct ListNode
{
int key;
int data;
struct ListNode *next;
};
struct HashTableNode
{
int bcount;
struct ListNode *next;
};
struct HashTable
{
int tsize;
int count;
struct HashTableNode **Table;
};
实施档案:
#include "hashing.h"
#include<stdio.h>
#include<stdlib.h>
struct HashTable *CreateHashTable(int size)
{
struct HashTable *h;
h = (struct HashTable *) malloc ( sizeof(struct HashTable) );
if(h == NULL)
{
printf("Memory Error");
return NULL;
}
h->tsize = (int) size/LOAD_FACTOR;
printf("h->tsize = %d",h->tsize);
h->count = 0;
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
if( h->Table == NULL )
{
printf("Memory Error");
return NULL;
}
int i;
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}
return h;
}
我会粘贴文件的其余部分或驱动程序文件,但我不认为它是相关的。 请告诉我为什么我会收到分段错误11
答案 0 :(得分:2)
你的问题在这里:
struct HashTableNode **Table;
您需要一个节点数组(不是二维数组),请更改为:
struct HashTableNode *Table;
也改变了
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
到
h->Table = malloc(sizeof(struct HashTableNode) * h->tsize);
我想我需要一系列指向节点的指针,不是吗?
正如@WhozCraig所指出的那样,没有理由增加间接水平。
示例A(指针):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a; /* pointer */
int i, n = 10;
a = malloc(n * sizeof(int)); /* space for 10 ints */
for (i = 0; i < n; i++) {
a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", a[i]);
}
free(a);
return 0;
}
示例B(指向指针):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int **a; /* pointer to pointer*/
int i, n = 10;
a = malloc(n * sizeof(int *)); /* space for 10 pointer to ints */
for (i = 0; i < n; i++) {
a[i] = malloc(sizeof(int)); /* space for 1 int */
*a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", *a[i]);
free(a[i]);
}
free(a);
return 0;
}
你可以看到两者都做同样的事情,但第一个需要更少的内存,代码更清晰。
让人们容易记住的一种方法是:
int *
可以包含数组
int **
可以保留一个表格(NROWS * NCOLS
)
int ***
可以包含一组表格
答案 1 :(得分:2)
您为指针数组分配了内存,但是您没有为此数组的成员分配内存。
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i] = malloc(...); //put correct arguments here and check allocation
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}