我有一个问题,我必须复制一个结构并将其添加到新的内存然后释放旧的内存。然后我必须增加为新内存创建空间并再次添加。我以为我的逻辑是正确的,但我一直遇到分段错误。我无法弄清楚我哪里出错了。
以下是我的结构的副本:
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
}
答案 0 :(得分:2)
我在这里看到多个错误:
free(book)
释放动态分配的struct book
但不释放动态分配的字段(book->title
,并且必须释放此类内容)memcpy
到book->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}}