下面的代码尝试创建一个存在类型的新变量(一种结构),但是当我通过 gdb 运行它时,它显示该变量在每次迭代中都具有相同的地址?局部变量在重新声明时不应该获得不同的地址吗?
presence* hashtable[MAX]; int i = 0; printf("---------ENTERING DATA FOR THE HASHTABLE------------------\n"); while (i < MAX) { presence item; /* Same address on every iteration */ printf("Enter item id : "); scanf("%d",&item.id); printf("Enter item name : "); item.name = (char*)malloc(SIZE*sizeof(char)); getchar(); fgets(item.name,SIZE,stdin); putItem(hashtable,&item); i++; }
当一个存在类型的项目被放入哈希表时,我应该分配内存然后分配项目还是简单地做(参考下面的代码)
int putItem(presence* hashtable[], presence* item) { int key = hash(item->id); hashtable[key] = (presence*)malloc(sizeof(presence)); /* Required or not? or do the below straight away?*/ hashtable[key] = item; }
4 回答
对于 1:您应该有presence *item;
指针类型变量,分配它并使用它来填充数据。您当前的实现在每次迭代中使用相同的变量。
while (i < MAX)
{
presence *item; /* pointer */
item = malloc(sizeof(*item));
printf("Enter item id : ");
scanf("%d",&item->id);
printf("Enter item name : ");
item->name = (char*)malloc(SIZE*sizeof(char));
getchar();
fgets(item->name,SIZE,stdin);
putItem(hashtable,item);
i++;
}
对于 2:您不需要分配内存。线
hashtable[key] = (presence*)malloc(sizeof(presence));
不需要。
但是,请确保key
小于MAX
的大小hashtable
。此外,您可能希望适当地处理冲突。
您的局部变量是易变的。创建实例时,当变量超出范围时它会消失。因此,您可能会在接下来的迭代中获得相同的地址。
在第二个实例中,您确实需要malloc
空间presence
并需要使用memcpy
. 而不是使用hashtable[key] = item
,你应该做memcpy ( hashtable[key], item, sizeof ( item ) );
- 局部变量通常只获得一个地址。当变量
item
在循环的后端超出范围时,编译器可以在下一次循环执行时自由地重用其存储空间。无论哪种方式,将指向局部变量的指针存储到比局部变量范围更长的数据结构是一个坏主意。 - 取决于你需要什么:如果哈希表中的值应该独立于传入的值,你应该在函数中分配内存。如果他们不应该,那么就不会。
局部变量在重新声明时不应该获得不同的地址吗?
我不明白为什么它是必须的(对于任何变量)。事实上,编译器将其放置在相同的内存位置是一个非常合乎逻辑的决定。
但是无论如何,您当前采用的方法是错误的:您在超出范围后使用本地(块范围自动)变量的地址,这是未定义的行为。您应该为各个元素动态分配内存。
当一个存在类型的项目放在哈希表中时,我应该分配内存然后分配项目还是简单地做
“简单”是指“不分配内存”吗?
除此之外,这完全取决于不同功能之间的契约是什么。另外,分配内存是为了什么?在您的特定情况下,这些行:
hashtable[key] = (presence*)malloc(sizeof(presence));
hashtable[key] = item;
会泄漏内存,因为您在分配后立即覆盖指向已分配内存的指针。所以不,不要进行内存分配。但是,如果您没有将哈希表(不是其中的项目!)声明为
presence* hashtable[MAX];
(即一个指针数组),但你有一个指向指针的指针:
presence **hashtable;
您将不得不为哈希表分配内存(显然是在插入函数之外):
presence **hashtable = malloc(sizeof(*hashtable) * N_ITEMS);