C - 扩展结构数组,其中指针已存在于其中
C - Expanding an array of structs with pointers already existing inside it
我有一个这样声明的结构数组
typedef struct bucket{
char * value;
char * key;
}BUCKET;
typedef struct item{
struct bucket * data;
struct item * next;
struct item * prev;
}ITEM;
typedef struct base{
struct item * first;
}BASE;
typedef BASE *SPACE;
它非常适合我必须用它做的一切。基本上我必须在 C 中实现哈希图。我设法做到了,但我完全陷入了这个任务。我需要让用户调整哈希图的大小。
如果我想要一个大小为 5 的 hashmap,我会这样做:
SPACE *hashmap = malloc(sizeof(SPACE *) * 5);
它完全符合程序的目的。
但是,如果我尝试使用以下代码块调整它的大小:
void expandHashspace(SPACE *hashmap){
printf("Please enter how large you want the hashspace to be.\n");
printf("Enter a number between %d and 100. Enter any other number to exit.\n>",hashSpaceSize);
int temp = 0;
scanf("%d",&temp);
if(temp>100 || temp<hashSpaceSize){
printf("Exiting...\n");
}
else {
SPACE *nw = NULL;
nw = realloc(hashmap, sizeof(SPACE *) * temp);
hashmap = nw;
hashSpaceSize = temp;
printf("Your hashspace is now %d rows long.\n", hashSpaceSize);
}
}
它也能正常工作。但是,当我去使用 hashmap 本身时,它以分段错误结束。或者 SIGSEGV 信号 11.
比如我有如下显示功能
void displayHashspace(SPACE *hashmap){
printf("\n");
int j = 0;
for(int i = 0; i < hashSpaceSize && hashmap; i++){
BASE *linkedList = hashmap[i];
if(linkedList) {
ITEM *node = linkedList->first;
printf("\n[HASH %d]\n", i);
while (node) {
printf("\t[BUCKET %d]\n\t[VALUE] : %s\n\t[KEY] : %s\n\n",j, node->data->value, node->data->key);
node = node->next;
j++;
etc...
使用CLion的调试,我意识到:
假设 hashmap 大小为 3。这意味着只有 hashmap[0-2] 存在。
如果我将 hashmap 的大小调整为,比方说 10,它允许我调整大小。
但是在显示的时候,hashmap[3]的地址真的很奇怪。
其他地址都很长,几乎有 8 位或更多,而 hashmap[3] 的地址总是 0x21
。
此后,一旦到达ITEM *node = linkedList->first;
,linkedList为hashmap[3],就出现了segmentation fault
这是另一个例子。这是我的保存功能:
void saveHash(SPACE *hashmap){
FILE *f = fopen("hashmap.hsh","w");
fprintf(f,"%d\n",hashSpaceSize);
for(int i = 0; i < hashSpaceSize;i++){
if(hashmap[i]){
ITEM *save = hashmap[i]->first;
do{
fprintf(f,"---\n%s\n%s\n",save->data->value,save->data->key);
save = save->next;
}while(save);
etc...
在这里,故事是不同的。它只能在调整大小后崩溃之前到达 hashmap[0]。使用调试器,我发现不知何故,设置为 hashmap[0]->first(通常在扩展之前工作)的保存有一个 BUCKET,其 VALUE 变量由于某种原因突然设置为 NULL,因此崩溃。
我尝试将扩展后的每个 "new" BASE 设置为 NULL,但在使用 expandHashspace()
后保存功能仍然中断。
我做错了什么?
将内存重新分配给 hashmap 无效,因为 hashmap 在该方法中是一个局部变量。意味着一切都变成了一场令人困惑的噩梦。
返回 hashmap 本身而不是什么都不返回解决了所有问题。
我有一个这样声明的结构数组
typedef struct bucket{
char * value;
char * key;
}BUCKET;
typedef struct item{
struct bucket * data;
struct item * next;
struct item * prev;
}ITEM;
typedef struct base{
struct item * first;
}BASE;
typedef BASE *SPACE;
它非常适合我必须用它做的一切。基本上我必须在 C 中实现哈希图。我设法做到了,但我完全陷入了这个任务。我需要让用户调整哈希图的大小。
如果我想要一个大小为 5 的 hashmap,我会这样做:
SPACE *hashmap = malloc(sizeof(SPACE *) * 5);
它完全符合程序的目的。
但是,如果我尝试使用以下代码块调整它的大小:
void expandHashspace(SPACE *hashmap){
printf("Please enter how large you want the hashspace to be.\n");
printf("Enter a number between %d and 100. Enter any other number to exit.\n>",hashSpaceSize);
int temp = 0;
scanf("%d",&temp);
if(temp>100 || temp<hashSpaceSize){
printf("Exiting...\n");
}
else {
SPACE *nw = NULL;
nw = realloc(hashmap, sizeof(SPACE *) * temp);
hashmap = nw;
hashSpaceSize = temp;
printf("Your hashspace is now %d rows long.\n", hashSpaceSize);
}
}
它也能正常工作。但是,当我去使用 hashmap 本身时,它以分段错误结束。或者 SIGSEGV 信号 11.
比如我有如下显示功能
void displayHashspace(SPACE *hashmap){
printf("\n");
int j = 0;
for(int i = 0; i < hashSpaceSize && hashmap; i++){
BASE *linkedList = hashmap[i];
if(linkedList) {
ITEM *node = linkedList->first;
printf("\n[HASH %d]\n", i);
while (node) {
printf("\t[BUCKET %d]\n\t[VALUE] : %s\n\t[KEY] : %s\n\n",j, node->data->value, node->data->key);
node = node->next;
j++;
etc...
使用CLion的调试,我意识到:
假设 hashmap 大小为 3。这意味着只有 hashmap[0-2] 存在。
如果我将 hashmap 的大小调整为,比方说 10,它允许我调整大小。
但是在显示的时候,hashmap[3]的地址真的很奇怪。
其他地址都很长,几乎有 8 位或更多,而 hashmap[3] 的地址总是 0x21
。
此后,一旦到达ITEM *node = linkedList->first;
,linkedList为hashmap[3],就出现了segmentation fault
这是另一个例子。这是我的保存功能:
void saveHash(SPACE *hashmap){
FILE *f = fopen("hashmap.hsh","w");
fprintf(f,"%d\n",hashSpaceSize);
for(int i = 0; i < hashSpaceSize;i++){
if(hashmap[i]){
ITEM *save = hashmap[i]->first;
do{
fprintf(f,"---\n%s\n%s\n",save->data->value,save->data->key);
save = save->next;
}while(save);
etc...
在这里,故事是不同的。它只能在调整大小后崩溃之前到达 hashmap[0]。使用调试器,我发现不知何故,设置为 hashmap[0]->first(通常在扩展之前工作)的保存有一个 BUCKET,其 VALUE 变量由于某种原因突然设置为 NULL,因此崩溃。
我尝试将扩展后的每个 "new" BASE 设置为 NULL,但在使用 expandHashspace()
后保存功能仍然中断。
我做错了什么?
将内存重新分配给 hashmap 无效,因为 hashmap 在该方法中是一个局部变量。意味着一切都变成了一场令人困惑的噩梦。
返回 hashmap 本身而不是什么都不返回解决了所有问题。