我正在使用C和手动内存管理并使用我的代码,我注意到了这一点:
假设我有
int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
int c = 10;
如果我拿这些数字并执行此操作:
*a = c;
然后a
将指向内存中与c
分开的不同位置,但其值为c
。如果我用过:
memcpy(a, &c, sizeof(int));
同样的事情会发生。不同的指针,相同的值。
我的问题是一个人是否比另一个更好?我知道char *
通常使用的是memcpy
或strcpy
,但是对于整数来说呢?一般指针怎么样?作业是否正常?
P.S。 我也知道
a = &c;
会使a
指向与c
相同的内存位置,因此有其值,但我认为这样会在a
free
之后留下一个悬挂指针永远不会在a
的内存中调用,所以我不会使用它。
答案 0 :(得分:5)
在您的示例中,您应该使用*a = c;
,因为您只想复制单个值。
如果需要复制数组的多个连续元素,请使用memcpy
。
答案 1 :(得分:3)
具体实施。一些编译器(包括GCC)能够很好地优化(至少gcc -O2
),调用标准函数memcpy
和memset
(作为我以前的同事) Pascal Cuoq评论说,可能内联高效的分配机器代码);有时,GCC甚至可以优化某些结构的赋值,因为对memcpy
的调用(有时,调用高效memcpy
例程对于足够大的struct
来说更快,包括结构赋值;在在其他情况下,通过某些memcpy
转换的对__builtin_memcpy
的调用被内联为一个有效的赋值代码,甚至可以通过寄存器而不使用任何内存)
您可以使用foo.c
编译gcc -fverbose-asm -O2 -march=native -S foo.c
示例,然后查看生成的foo.s
因此,如果您使用最近的 GCC或Clang/LLVM编译器(或其他一些好的编译器)并启用优化,那么您应该使用memcpy
和memset
...
换句话说,memcpy(a, &c, sizeof(int));
可以像*a = c;
一样有效地进行优化(如果您定义一个"类型泛型"宏,例如使用C99中的_Generic,会使用memcpy
并且应该有效地进行优化。
答案 2 :(得分:0)
是否应该始终使用memcpy?
简单明了,没有。
编写代码的第一个目标是使其易于理解和维护。当*a = c
被声明为指向int的指针并且a
被声明为int时,每个人都知道c
会做什么。编译器也确切地知道你的意思。您永远不会看到编译器优化您的*a = c
来调用memcpy
,因为这将是一种不优化。
当*a=c
类型为memcpy
时,您会看到编译器优化c
来调用struct AVeryLargeStruct
,并且a
是指向该*a=c
的指针。没有必要将memcpy(a,&c, sizeof(c))
转换为*a=c
,因为编译器会为您执行此操作,免费提供。写memcpy
因为它比memcpy
更容易出错,更不容易出错。
有些地方您确实需要使用memmove
(或memcpy
):
首先是标准操作程序;阅读您的代码并在该上下文中使用memcpy
时,没有人会感到震惊。后两者不是SOP。在该上下文中memcpy
的用法将使读者暂停代码。这是一件好事,因为你在那里做了一些有点棘手的事情。将memcpy
隐藏在memcpy
之中的那些棘手的电话隐藏在memcpy
,您可以使用普通的任务,这使得您绝对需要使用command
的几个地方无法脱颖而出。只有你的目标是赢得IOCCC,这才是一件好事。
如果您在任何地方使用command.ExecuteNonQuery();
,那么您可能会使代码速度变慢,并且您更有可能让其他人认为您的代码存在问题。