c 中结构的动态内存分配



我正在尝试通过使用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->name = (char*)malloc(MAX_LEN*sizeof(*name_dict->name));
name_dict->prob = (prob_t*)malloc(MAX_PROB*sizeof(*name_dict->prob));
return name_dict;
}

但是当我这样做时,它会将内存分配给结构,而不是分配给它的任何成员指针(它们只指向垃圾(。

我做错了什么?谢谢

正如这里所解释的,malloc不会"清理"内存,然后可能会充满垃圾(因为例如,相同的内存是由另一个调用返回的malloc()、 使用然后free()(。三种经典解决方案是:

  • 忍受它。手动设置struct的所有成员(如果您是 使用malloc分配struct(之前使用struct(或通常将所有获得的内存设置为所需的值(
  • 使用前使用memset将所有内存清零
  • 使用calloc而不是malloc(请注意,它的签名略有不同(。calloc类似于malloc+memset。举个例子:

name_t *init_name_dict() {
name_t *name_dict;
name_dict = calloc(MAX_LINES, sizeof(*name_dict));
name_dict->name = calloc(MAX_LEN, sizeof(*name_dict->name));
name_dict->prob = calloc(MAX_PROB, sizeof(*name_dict->prob));
return name_dict;
}

作为旁注,在 C 中,您不需要/不应该强制转换由malloc/calloc返回的指针(但如果实际上您使用的是 C++ 编译器,那么您必须强制转换它......

如果你想要清除内存(而不是包含垃圾的内存(,你需要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字段,则应更改name_t定义到

typedef struct { char name[MAX_LEN]; prob_t prob[MAX_PROB]; } name_t;

并一次性分配所有MAX_LINES name_t:calloc(MAX_LINES, sizeof(name_t)).

如果您需要原始name_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++向量构造函数,它为 单元格类型。

结构

typedef struct {
char *name;
prob_t *prob;
} name_t;

有两个指针作为成员。因此,在 32 位操作系统上,sizeof(name_t)是 8 个字节。 动态创建name_t结构体实例

name_t *name_dict = (name_t*)malloc(sizeof(name_dict));

仅分配 8 个字节来存储两个指针。正如xanatos所说,分配的内存是垃圾,指针将指向随机位置。您可以在分配时使用calloc()name_dict或手动将其name_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_LINES这里(假设你只想在这里创建一个结构(

    name_dict = (name_t*)malloc(MAX_LINES*sizeof(*name_dict));

  • MAX_PROB这里(假设您只想创建一个结构 这里(

    name_dict->prob = (prob_t*)malloc(MAX_PROB*sizeof(*name_dict->prob));

相关内容

  • 没有找到相关文章

最新更新