复制到C&;中的空位置时崩溃;正在传递的数据无效

复制到C&;中的空位置时崩溃;正在传递的数据无效,c,memory,crash,null,C,Memory,Crash,Null,我有以下结构: struct PList{ Person value; PList* next; } 及 及 在主要方法中: Person n; // n is inputted from the user addPersonToList(&n, &customers); //customers is a PList 这是addPersonToList的代码: void addPersonToList(Person* p, PList* pdb) {

我有以下结构:

struct PList{
    Person value;
    PList* next;
}

在主要方法中:

Person n;
// n is inputted from the user
addPersonToList(&n, &customers); //customers is a PList
这是addPersonToList的代码:

void addPersonToList(Person* p, PList* pdb) {
        PList* db;
        db = pdb;
        while (db->next != NULL ) {
                db = db->next;
        }
        PList a;
        a = createNewPList();  // this simply assigns next to NULL and value to an empty Person
        a.value = *p;
        memcpy(db->next,&a,sizeof(PList)+sizeof(Person)+sizeof(PersonID));
}
这是createNewPList

PList createNewPList() {
        PList a;
        a.next = NULL;
        a.value = constructPerson("", constructPersonID(' ', 0), 0);
        return a;
}
问题1未解决 调用addPersonToList方法时,除了p->Id.number之外,Person中的所有值都被正确传递。这在方法调用之前和方法调用之后完全混淆了

问题2已解决 我没有使用memcpy,而是尝试了db->next=a;以及手动分配所有值。 然而,在那一行程序正在崩溃,我假设因为db->next当前为空

至于错误,没有显示任何错误。程序只是崩溃了

感谢您提供的任何解决方案

while (db->next != NULL )
/* ... */
memcpy(db->next
根据定义,这总是错误的,因为它总是将
memcpy
转换为
NULL
。您需要将内容分配到
db->next
。我想你只需要放下
memcpy
,然后说:

db->next = createNewPList();
编辑 在看到更多精彩的代码后,您可能希望:

db->next = malloc(...);
memcpy(db->next, &a ... );
你有

while (db->next != NULL )
/* ... */
memcpy(db->next
根据定义,这总是错误的,因为它总是将
memcpy
转换为
NULL
。您需要将内容分配到
db->next
。我想你只需要放下
memcpy
,然后说:

db->next = createNewPList();
编辑 在看到更多精彩的代码后,您可能希望:

db->next = malloc(...);
memcpy(db->next, &a ... );
您的
createNewPList()
应该返回一个指针,指向堆上分配的内容:

PList*
createNewPList(void)
{
        PList*    a;

        if ((a = malloc(sizeof(*a)) == NULL)
            return NULL;
        a->next = NULL;
        a->value = constructPerson("", constructPersonID(' ', 0), 0);
        return a;
}
然后,您应该忘记这个
memcpy()
,只需将您的
next
设置为
createNewPList()
的返回值:

不要忘了浏览你的
链表
,并在你不再需要的时候释放所有指针。

你的
createNewPList()
应该返回一个指向堆上分配的某些内容的指针:

PList*
createNewPList(void)
{
        PList*    a;

        if ((a = malloc(sizeof(*a)) == NULL)
            return NULL;
        a->next = NULL;
        a->value = constructPerson("", constructPersonID(' ', 0), 0);
        return a;
}
然后,您应该忘记这个
memcpy()
,只需将您的
next
设置为
createNewPList()
的返回值:



不要忘记浏览你的
链表
,在你不再需要它们时释放所有指针。

你不能将memcpy设置为NULL。那只是。。。错误的o_o你甚至希望它做什么?
sizeof(struct PList)
包含它的所有成员和子成员的大小。修复了sizeof。如果我想要一些东西,那么除了复制到null还有什么选择呢?复制到
null
总是会引发未定义的行为。您需要以某种方式分配有效内存,以便将某些内容复制到。@mangusbrother查看
manmalloc
您不能将memcpy设置为NULL。那只是。。。错误的o_o你甚至希望它做什么?
sizeof(struct PList)
包含它的所有成员和子成员的大小。修复了sizeof。如果我想要一些东西,那么除了复制到null还有什么选择呢?复制到
null
总是会引发未定义的行为。您需要以某种方式分配有效内存,以便将某些内容复制到。@mangusbrother查看
manmalloc
*db->next=createNewPList();但是添加createNewPList会导致崩溃details@mangusbrother不要添加*
createNewPList()
似乎没有返回对
PList
的引用。可能,
createNewPList()
应该在堆上而不是堆栈上创建节点。让
createNewPList
在堆上构建节点(使用
malloc
)。这将为您提供一个漂亮、持久的指针,您可以毫无问题地返回该指针(除了确定谁负责释放此新指针)。*db->next=createNewPList();导致崩溃,但添加了createNewPListdetails@mangusbrother不要添加*
createNewPList()
似乎没有返回对
PList
的引用。可能,
createNewPList()
应该在堆上而不是堆栈上创建节点。让
createNewPList
在堆上构建一个节点(使用
malloc
)。这将为您提供一个漂亮、持久的指针,您可以毫无问题地返回它(除了确定谁负责释放这个新指针)。有副作用的情况是邪恶的!;)在程序终止之前,这些值都是必需的,所以我假设在关闭程序时会自动释放内存?是的,任何桌面操作系统都会处理剩余的未释放内存。但是,我认为自己清理内存是一个好习惯,如果有一天你在一个不知名的平台上工作,由于某种原因无法处理它,那会怎么样但是,对于一项任务来说,s是非常重要的,而且这超出了我的要求,我相信是的,因为在这种情况下,我不会从中受益,这不值得花时间。有副作用的条件是邪恶的!;)这些值在程序终止之前都是需要的,所以我假设在关闭程序时,这些值会自动释放?是的,任何桌面操作系统都将处理剩余的未释放内存。然而,我认为自己清理是一个好习惯,如果有一天你在一个不知名的平台上工作,因为某种原因而无法处理它,那会怎么样?这是一个任务,但这比我认为需要的要多,因为我在这种情况下不会真正受益,所以不值得花时间。