c语言中结构的动态内存分配
我试图通过使用malloc为结构及其指针成员分配内存来初始化结构:c语言中结构的动态内存分配,c,pointers,dynamic,struct,malloc,C,Pointers,Dynamic,Struct,Malloc,我试图通过使用malloc为结构及其指针成员分配内存来初始化结构: typedef struct { char *name; prob_t *prob; } name_t; 我知道一旦初始化结构,我需要分别为指针分配内存: name_t *init_name_dict() { name_t *name_dict; name_dict = (name_t*)malloc(MAX_LINES*sizeof(*name_dict)); name_dict-&g
typedef struct {
char *name;
prob_t *prob;
} name_t;
我知道一旦初始化结构,我需要分别为指针分配内存:
name_t
*init_name_dict() {
name_t *name_dict;
name_dict = (name_t*)malloc(MAX_LINES*sizeof(*name_dict));
name_dict->name = (char*)malloc(MAX_LEN*sizeof(*name_dict->name));
name_dict->prob = (prob_t*)malloc(MAX_PROB*sizeof(*name_dict->prob));
return name_dict;
}
但当我这样做时,它会将内存分配给结构,而不是它的任何一个成员指针,它们只是指向垃圾
我做错了什么?谢谢结构
typedef struct {
char *name;
prob_t *prob;
} name_t;
有两个指针作为成员。因此,在32位操作系统上,sizeofname\u t是8字节。
name\u t struct实例的动态创建
只分配8个字节来存储两个指针。正如xanatos所说,分配的内存是垃圾,指针将指向随机位置。您可以在分配名称\u dict时使用calloc,也可以手动将其置空name\u dict->name=NULL;name_dict->prob=NULL;。您也可以不受指针内容的困扰,在下一个代码行中为成员分配内存
name_dict->name = (char*)malloc(MAX_LEN*sizeof(char));
name_dict->prob = (prob_t*)malloc(sizeof(prob_t));
您还可以检查内存分配是否良好,以及两个指针是否都不指向NULL
总之,正确编写init_name_dict方法
name_t * init_name_dict()
{
name_t *name_dict = (name_t*)malloc(sizeof(name_t));
if (name_dict != NULL)
{
name_dict->name = (char*)malloc(MAX_LEN*sizeof(char)));
name_dict->prob = (prob_t*)malloc(sizeof(prob_t));
}
return name_dict;
}
您的代码中的错误已被删除
此处的MAX_行假定您只希望在此处创建一个结构
name_dict=name_t*mallocMAX_line*sizeof*name_dict
这里假设您只想创建一个结构
这里
name\u dict->prob=prob\u t*mallocMAX\u prob*sizeof*name\u dict->prob
如前所述,malloc不会清理内存,而内存可能会充满垃圾,因为例如,另一次调用malloc返回了相同的内存,使用后释放。三个经典解决方案是:
接受它。如果需要,请手动设置结构的所有成员
在使用结构之前使用malloc分配结构,或者通常将所有获得的内存设置为所需的值
在使用之前,请使用memset将所有内存归零
使用calloc而不是malloc注意,它的签名稍有不同。calloc类似于malloc+memset。例如:
作为旁注,在C中,您不需要/不应该强制转换malloc/calloc返回的指针。如果您希望清除内存而不是内存中有垃圾,则需要calloc 而不是malloc,但那是微不足道的 更大的问题是:
1) no error checking
2) possibly needless malloc calls
3) you're allocating MAX_LINES of theses name_t structure but initializing
only one of them
如果.name和.prob字段无法重新分配,则应更改您的名称\u t
定义
typedef struct { char name[MAX_LEN]; prob_t prob[MAX_PROB]; } name_t;
并一次性分配所有最大行名称:callocMAX\u行、sizeofname\t
如果您需要原始名称\u t结构,那么我需要一个初始值设定项:
int init_name_dict (name_t *this)
{
if(0==(this->name=calloc(MAX_LEN, sizeof *this->name))) return -1;
if(0==(this->prob=calloc(MAX_PROB, sizeof *this->prob))){ free(this->name); return -1; }
return 0;
}
它的析构函数
void destroy_name_dict(name_t *this) { free(this->name); free(this->prob); }
然后是整个阵列的初始化分配器:
name_t* new_name_dicts(void)
{
name_t *r = malloc(MAX_LINES*sizeof *r);
if(!r) return r;
int i;
for(i=0; i<MAX_LINES; i++)
if(0>init_name_dict(&r[i])) goto fail;
return r;
fail:
for(--i; i>=0; --i)
destructor_name_dict(&r[i]);
return NULL;
}
基本上,什么将是一个C++向量构造函数,它可以为
单元格类型。malloc方法不会清除它返回的内存。如果您想要归零内存,请使用calloc,或者使用memset。我觉得你的代码看起来不错,只是你没有检查malloc的返回值,也没有必要在C中强制转换malloc的返回值。请注意@xanatos注释中隐含的区别:一个指向空间的有效指针(其中包含垃圾)与一个无效指针完全不同。当malloc失败时,它返回一个空指针。在C中,所有这些强制转换都是不必要的。您似乎误解了OP的主要问题。虽然如果检查malloc调用的结果,他的代码会更加健壮,但基本上没有问题。His是一个关于正确分配的指针指向的内存内容的错误期望的问题;是错误的,因为它只分配指针的大小。OP做得很好。你没有纠正这个问题,所以在32位操作系统上,sizeofname\u t是8字节。还有,为什么你要提到这个:动态创建name\t struct name\u t*name\u dict=name\t*mallocsizeofname\u dict的实例;只分配8个字节来存储两个指针。?OP不是这样做的。
void destroy_name_dict(name_t *this) { free(this->name); free(this->prob); }
name_t* new_name_dicts(void)
{
name_t *r = malloc(MAX_LINES*sizeof *r);
if(!r) return r;
int i;
for(i=0; i<MAX_LINES; i++)
if(0>init_name_dict(&r[i])) goto fail;
return r;
fail:
for(--i; i>=0; --i)
destructor_name_dict(&r[i]);
return NULL;
}