如何正确分配具有char *字段的struct *

时间:2013-12-09 21:55:22

标签: c

我使用malloc分配指向head结构的指针,但我希望'title'字段的大小为100个char元素。如何正确地做到这一点?

struct tail{
    int x;
};

struct head{
    char *title;
    struct tail *next;
};

void function(){
    struct head *h;
    //this (program won't know how much to allocate for 'title':
    h = (struct head*)malloc(sizeof(struct head));

    //VS this (Segmentation fault (core dumped)):
    h->title = (char*)malloc(sizeof(char)*255);
    h->next = (struct tail*)malloc(sizeof(struct tail*));

    /*
    or maybe I should alloc h, then realloc title?
    If that's the answer, how will I free whole structure later?
    */
}

PS。我没有故意使用char title[100]

编辑备注。 (char)是一个错字,我的代码中有(char *)

3 个答案:

答案 0 :(得分:2)

您是否正在使用-wall进行编译?

如果你看一下这个警告你应该

so.c:16:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

malloc的返回值是一个void指针,它指向你正在分配的内存 - 你将内存的地址转换为char,这是因为你错过了指针声明*,从而截断实际地址,然后导致您的段错误。

C确实知道从一开始就为结构分配多少内存,因为指针具有固定的大小,这是在头/尾结构上执行malloc时分配的全部内容。

答案 1 :(得分:0)

为什么不使用第一种方式,然后为title分配空间?

h = malloc(sizeof(struct head));
h -> title = malloc(sizeof(char) * 100);
h -> next = malloc(sizeof(struct tail*));

诀窍是要记住titlechar *,因此h中所需的只是指针的空间,而不是实际的数组。

您只需使用以下内容即可释放:

free(h -> title);
free(h -> next);
free(h);

第二种方法的问题是没有分配h,所以它是分段的。另外,你将malloc(void *)的结果转换为char,这实际上没有意义 - 我认为你想要转换为char *,这不是'无论如何都需要,因为C可以自动转换void *

答案 2 :(得分:0)

你可以做一些像创建一个创建具有给定标题大小的结构头的函数。请记住,您必须(应该)创建一个free_head函数,该函数能够销毁由下面的create_head函数创建的对象。

struct head* create_head( unsigned title_size) {
     struct tail* t = malloc (sizof(struct tail) );
     if ( ! tail ){
         return NULL;
     }
     char* title = malloc ( title_size * sizeof(char) );
     if ( !title ){
          free(t)
          return NULL;
     }
     struct head* h = malloc (sizeof (struct head) );
     if ( !head ){
         free (t);
         free (title);
         return NULL;
     }
     head->title = title;
     head->next = t;
     return head;
}

现在你可以简单地使用像:

这样的功能
struct head* = create_head(100);

然后当然你需要写一些代码来正确地破坏struct head,否则你会创建一个内存泄漏。还要记住,此函数不会为终止'\ 0'字节分配一个额外的字符。终止C字符串

更迭!