繁体   English   中英

在c中为结构动态分配内存

[英]Dynamic memory allocation for structs in 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之前,先手动设置struct所有成员(如果使用malloc分配struct )(或通常将所有获得的内存设置为所需的值)
  • 使用memset将所有内存归零后再使用
  • 使用calloc代替malloc (请注意,其签名略有不同)。 callocmalloc + 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中,您不需要/也不应该calloc 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位OS上, sizeof(name_t)为8个字节。 动态创建name_t结构实例

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

仅分配8个字节来存储两个指针。 正如xanatos所说,分配的内存是垃圾,指针将指向随机位置。 您可以在分配name_dict时使用calloc()或将其手动无效化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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM