使用包含多个元素的struct的malloc

时间:2015-01-07 12:03:29

标签: c struct malloc

我在这里做错了什么?

我有一个QueueElement结构,包含一个char *文本和一个指向下一个元素的指针,所以显然是一个链表:

//QElement as in QueueElement
struct QElement {
    char* text;
    struct QElement* next;
};
typedef struct QElement QElement;

...

void enqueue (char* string){
QElement *new = (QElement *)malloc(sizeof(QElement)); 
//QElement cast is probably redundant but it doesn't hurt anyone
strcpy (new->text, string);

//some other stuff happening here, linking to other element in linked list, 
//but thats not of interest at the moment

}

...

如果我试图在main函数中排队一个单词,我会继续得到分段错误,而valgrind告诉我,当我使用strcpy时我做错了,所以我的malloc似乎是不正确的。我该怎么做?

4 个答案:

答案 0 :(得分:3)

在此代码中

strcpy (new->text, string);

new->text未分配内存。它可能包含一些垃圾值,或者一些写保护的内存地址甚至是NULL。将该指针传递给strcpy()会导致Undefined behaviour,并且作为副作用,您可能会遇到分段错误。

您可以使用strdup()或在new->text之前将内存分配给strcpy() - 指向该指针。在这两种情况下,您需要free()之后分配的内存。

另外,

  1. do not cast malloc()
  2. 的返回值
  3. 在使用指针之前检查动态内存分配[malloc() / calloc()]是否成功。

答案 1 :(得分:3)

其他答案推荐的

strdup(.)是非标准的。如果您不在Unix平台上,它可能无法使用。

然而,重点是正确的。您需要分配内存来存储字符串。

尝试:

const size_t sz=(strlen(string)+1)*sizeof(*string);//Space required. Including '\0' terminator.
new->text=malloc(sz);//space allocated.
if(new->text==NULL){//sz never 0 because +1.
   exit(EXIT_FAILURE);//Allocation failed in non-error handled function.
}
memcpy(new->text,string,sz); //typically fastest way to copy!

而不是strdup(.)

我对sizeof(*string)的使用实际上是不必要的(因为它总是1)但编译器会发现它并且它只是一个好习惯。

有一天,世界将更加统一地移动到多字节字符,这段代码已准备好迎接光辉的曙光!

当您使用了QElement'时,请不要忘记free(.)。 您应该写一个这样的函数:

void QElementDestroy(QElement*const element){
    if(element==NULL){
        return;//Nothing to do!
    }
    free(element->text);//Needs NULL protection.
    free(element);//Does not need NULL protection. But we've done the test anyway!
    //NB: Order matters here. A lot.
}

当您完成enqueue(.)返回的值时调用它。

如果你想让字符串“直播”。在调用destroy之前元素集element->text=NULLfree(NULL)无需做任何事情并正常返回。

PS:我认为strdup(.)有点像n00b陷阱。他们需要一段时间来匹配malloc(.)free(.)并且strdup(.)是一个叛徒,因为其他str...函数都没有为调用者预期分配空间到free(.)。它也是非标准的。

答案 2 :(得分:1)

因为您只为结构变量分配内存。您必须在结构成员中分配内存。

 new->text=malloc(10);//for example 

分配内存后,您可以使用strcpy函数。

答案 3 :(得分:1)

您已为new分配内存,但不为text成员变量分配内存。 为text分配内存并执行代码。