如何复制结构?

时间:2015-09-30 16:43:43

标签: c pointers segmentation-fault free memcpy

我有一个问题,我必须复制一个结构并将其添加到新的内存然后释放旧的内存。然后我必须增加为新内存创建空间并再次添加。我以为我的逻辑是正确的,但我一直遇到分段错误。我无法弄清楚我哪里出错了。

以下是我的结构的副本:

struct childrensBook *book = (struct childrensBook *) malloc(sizeof(struct childrensBook));     //Structure of book #1

book->title = (char *)malloc(100);                  //allows memmory of 100 characters                                                  
book->author = (char *)malloc(100);             //allows memmory of 100 characters  
book->publisher = (char *)malloc(100);              //allows memmory of 100 characters  
book->copyright = 0;
book->price = 0;

以下是我的添加功能的副本:

int addRecord() 
{
    int headptr = 0;
    struct childrensBook *book = malloc(sizeof(struct   childrensBook));            //get book structure
    struct childrensBook *book1 = malloc(sizeof(struct childrensBook));         //create structure book1
    memcpy(book->title, "We're Going on a Bear Hunt", 26);                      //populate fields of book 
    memcpy(book->author, "Michael Rosen", 13);                                  //populate fields of book 
    memcpy(book->publisher, "Little Simon", 12);                                //populate fields of book 
    book->copyright = 1989;                                                 //populate fields of book 
    book->price = 7.99;                                                     //populate fields of book 
    memcpy(book1, book, sizeof *book1);                     //copy fields of book to book 1
    free(book);
}

这是我对功能的呼吁:

else if(x==4)
{
    addRecord();
    fprintf(stderr, "You have added the record: %s\n", book->title);
    free(book);
    moveptr++;   //here to incrememnt for new space. This is a globaal variable
}

4 个答案:

答案 0 :(得分:2)

我在这里看到多个错误:

  • free(book)释放动态分配的struct book但不释放动态分配的字段(book->title,并且必须释放此类内容)
  • 您正在呼叫memcpybook->author和其他char*字段,但这些字段尚未动态分配,也许您想要book->title = strdup("literal")
  • memcpy(book1, book, sizeof *book1)至少有两个错误:首先你要处理sizeof *book1 bytes,这是指针的大小,而不是整个结构。然后你要复制的字段不包含原始类型,但指针会在两本书之间共享所有权,你应该复制每一个动态分配的字段。

只是为了开始提供一些代码:

void free_book(struct book* b) {
  free(b->title);
  free(b->author);
  ...
  free(b);
}

struct* book dupe_book(struct book* source) {
  struct book* dest = malloc(sizeof(struct book));
  dest->price = source->price;
  dest->author = strdup(source->author);
  ...
}

答案 1 :(得分:1)

memcpy不添加null终止符。因此,要么手动添加'\0' memcpy,要么增加memcpy中的字节数。

这样做 -

memcpy(book->title, "We're Going on a Bear Hunt", 26); // or use strncpy so it will add null terminator          
memcpy(book->author, "Michael Rosen", 14);                                   
memcpy(book->publisher, "Little Simon", 13);                              

因为book->title未终止,因此fprintf带有说明符%s会给出段错误。

如果您在malloc中使用固定内存(即100),为什么要使用它?将它们声明为数组 -

book->title = (char *)malloc(100);          // in struct declare title as char title[100]             
book->author = (char *)malloc(100);         // similar with rest.     
book->publisher = (char *)malloc(100);              

然后你不会对free采取紧张措施。

注意 - 如果您使用malloc,那么也会在评论中提及,请不要投放malloc的结果。

答案 2 :(得分:0)

不要忘记复制字符串文字的空终止符:

您需要使用"Little Simon", 13代替等等。"Little Simon"并不像您想象的那么少。它占用13个字节,而不是12个字节。

否则你的fprintf将超过你的字符串,带来灾难性后果:分段错误是一种可能性。

答案 3 :(得分:0)

在您的情况下,结构char包含指向字符串的指针。如果您想要该对象的深层副本,您还需要复制内部字符串。

但是,由于您对所有字符串字段使用常量长度,因此可以将所有字符串元素用作struct childrensBook { char title[100]; char author[100]; char publisher[100]; int copyright; int price; } /* the structure content may be written as follows */ strcpy(book->title, "We're Going on a Bear Hunt"); /* structure copy by direct assignment */ *book1 = *book; 数组。在这种情况下,整个内容将存储在一块内存中:

{{1}}