C 关于结构内存分配机制的一些困惑?
在我的项目中,我遇到了C程序C 关于结构内存分配机制的一些困惑?,c,linux,dynamic-memory-allocation,C,Linux,Dynamic Memory Allocation,在我的项目中,我遇到了C程序 如下所示,htmp是一个结构指针。我们首先为它分配一个内存。但是为什么我们要再次为它的元素word分配内存呢 如果必须为结构的每个元素分配内存,为什么不为它的其他元素分配内存,id和next #定义HASHREC bitewisehash typedef结构hashrec{ 字符*字; 长id; 结构hashrec*next; }哈什雷克; /*从Hugh Williams转到前面的散列和散列函数,http://www.seg.rmit.edu.au/code/zw
htmp
是一个结构指针。我们首先为它分配一个内存。但是为什么我们要再次为它的元素word
分配内存呢id
和next
#定义HASHREC bitewisehash
typedef结构hashrec{
字符*字;
长id;
结构hashrec*next;
}哈什雷克;
/*从Hugh Williams转到前面的散列和散列函数,http://www.seg.rmit.edu.au/code/zwh-ipl/ */
/*简单按位散列函数*/
无符号整数位哈希(char*word、int-tsize、无符号整数种子){
字符c;
无符号整数h;
h=种子;
对于(;(c=*word)!='\0';word++)h^=((h>2));
返回((无符号整数)((h&0x7fffffff)%tsize));
}
/*在哈希表中插入字符串,检查应不存在的重复项*/
void hashinsert(HASHREC**ht,char*w,long-long-id){
HASHREC*htmp,*hprv;
无符号int-hval=HASHFN(w,TSIZE,SEED);
对于(hprv=NULL,htmp=ht[hval];htmp!=NULL&&scmp(htmp->word,w)!=0;hprv=htmp,htmp=htmp->next);
if(htmp==NULL){
htmp=(HASHREC*)malloc(sizeof(HASHREC));#为htmp分配内存
htmp->word=(char*)malloc(strlen(w)+1);#为什么要再次分配内存?
strcpy(htmp->word,w);#
htmp->id=id;#为什么不为htmp->id分配内存?
htmp->next=NULL;#为什么不为htmp->next分配内存?
如果(hprv==NULL)ht[hval]=htmp;
else hprv->next=htmp;
}
else fprintf(标准,“错误,重复条目位于:%s.\n”,htmp->word);
返回;
}
当您为结构分配内存时,只为成员word
分配了足够的内存来容纳指针,该指针还必须指向您可以分配的有效内存
如果不指向有效内存,它的值是不确定的,尝试用不确定的值取消引用此类指针是未定义的行为。为结构分配内存时,只为成员
word
分配足够的内存来保存指针,该指针还必须指向可以分配的有效内存
如果不指向有效内存,它的值是不确定的,尝试用不确定的值取消引用此类指针是未定义的行为。您需要在脑海中区分两件事(1)我要存储的东西在什么内存中?;(2)哪个变量(指针)保存了它存储的地址,这样我就可以再次找到它 首先声明指向
struct hashrec
的两个指针:
HASHREC *htmp, *hprv;
指针只不过是一个变量,它将指向其他对象的地址作为其值。当您第一次声明这两个指针时,它们是未初始化的,没有地址。然后,您以一种相当尴尬的方式,在for
循环声明中初始化两个指针,例如hprv=NULL,htmp=ht[hval]
和之后的hprv=htmp,htmp=htmp->next
,所以现在可能两个指针都在某个地方持有地址和点
在循环之后(使用空的主体),测试if(htmp==NULL)
,这意味着htmp
不指向地址(如果您发现感兴趣的哈希索引为空,则可能是这种情况)
然后,为了为一个HASHREC
(例如struct HASHREC
)提供存储,您需要分配存储空间,以便有一块内存来存储您想要存储的东西。因此,分配一个块来保存一个结构。(见:)
现在,看看您分配了哪些内存:
typedef struct hashrec {
char *word;
long long id;
struct hashrec *next;
} HASHREC;
您已经为包含(1)一个char*字的结构分配了存储空间代码>(指向char-8字节(x86上为4字节)的指针);(2) a长id代码>(两个都是8字节)和(3)一个指针,用于保存序列中下一个HASHREC
的地址
毫无疑问,id
可以保存一个long
值,但是word
和next
呢?它们都是指针。指针代表什么?他们指的东西可以找到的地址。在哪里可以找到word
?您想要的东西当前由w
指向,但不能保证w
将继续保留您想要的单词,因此您将制作一份副本并将其作为HASHREC
的一部分存储。你看:
htmp->word = malloc(strlen(w) + 1); /* useless cast removed */
现在malloc
返回什么?它将地址返回到新内存块的开头,strlen(w)+1
字节长。由于指针持有其他内容的值作为其值,htmp->word
现在将新内存块开头的地址作为其值存储。因此htmp->word
“指向”新的内存块,您可以使用htmp->word
作为引用来引用该内存块
接下来发生的事情很重要:
strcpy(htmp->word, w); #
htmp->id = id; # why not allocate memory for htmp->id ?
htmp->next = NULL; # why nor allocate memory for htmp->next?
strcpy(htmp->word,w)代码>将w
复制到新的内存块中<代码>htmp->id=id
将id
的值分配给htmp->id
并且不需要分配,因为分配时:
htmp = malloc(sizeof(HASHREC)); /* useless cast removed */
为(1)char*
指针分配存储空间,(2)为长id分配存储空间代码>和(3)一个struct hashrec*
指针——您已经为long
分配了一个htmp->id
指针,因此id
可以将id
的值存储在long
的内存中
htmp->next = NULL; # why nor allocate memory for htmp->next?
您试图存储的内容是什么,需要为htmp->next
重新分配?(提示:当前无任何内容)它将指向下一个struct hashrec
。目前它被初始化为N
htmp->next = NULL; # why nor allocate memory for htmp->next?
{
word = Elephant
id = 1245
}