我在创建一个将从参数添加(复制)结构到调整大小的数组的函数时出现问题。
这是我的简化代码:
typedef struct User
{
char FirstName[32];
char LastName[32];
}
User;
User * Users
unsigned short UsersNum = 0;
void AddUser(User * NewUser)
{
Users = (User *) realloc(Users, (UsersNum + 1) * sizeof(User));
memcpy(Users[UsersNum], NewUser, sizeof(User));
UsersNum++;
}
我得到了这个:
error: incompatible type for argument 1 of `memcpy'
我也试过
memcpy(Users + UsersNum, NewUser, sizeof(User));
但得到了SEGFAULT。
如何将NewUser复制到用户的末尾?
答案 0 :(得分:3)
首先,please don't cast the return value of malloc()
in C。
其次,为什么你觉得必须在这里使用memcpy()
? memcpy()
函数很棒,但它是一个相当钝的工具,意在“盲目地”复制大部分内存,而这些内存没有程序所知的其他结构。在您的情况下,您知道您复制的字节构成了User
类型的实例,即它只是User
类型的值。
值通常由赋值移动,因此请改用:
void AddUser(const User *NewUser)
{
User *UsersGrown = realloc(Users, (UsersNum + 1) * sizeof *Users);
if(UsersGrown != NULL)
{
Users = UsersGrown;
Users[UsersNum] = *NewUser;
++UsersNum;
}
}
您可以看到我也创建了参数const
,并添加了一些基本的错误检查,因为realloc()
可能会失败。
将Users
数组的分配的大小与数组的 length 分开是个好主意,这样你就可以在不同的速度并减少了对realloc()
的呼叫次数。换句话说,为例如分配空间首先是8个元素,当它被击中时,大小加倍realloc()
,依此类推。如果您期望进行多次插入,这会提供更好的性能。
答案 1 :(得分:1)
你应该问问自己,User[UsersNum]
是什么类型...... User
,memcpy
对指针进行操作。要获得它的地址,有&
个操作数。所以它应该是
memcpy(&Users[UsersNum], NewUser, sizeof(User));
另请注意,您使用非常低效的方式来实现该功能。应该避免复制/移动这么多东西。