Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中结构的动态内存分配_C_Pointers_Dynamic_Struct_Malloc - Fatal编程技术网

c语言中结构的动态内存分配

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

我试图通过使用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;
}
但当我这样做时,它会将内存分配给结构,而不是它的任何一个成员指针,它们只是指向垃圾

我做错了什么?谢谢

结构

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;
}