memcpy(),size参数的值应该是多少?
我想将一个 int
数组复制到另一个 int
数组。它们使用相同的长度定义,因此它们的长度始终相同。
memcpy()
的大小参数的以下两种替代方案有何优缺点?
memcpy(dst, src, ARRAY_LENGTH*sizeof(int));
或者
memcpy(dst, src, sizeof(dst));
第二个选项总是有效吗?与内容无关?
有利于最后一个的一件事是,如果数组发生更改,则更新 memcpy()
需要进行一些内务处理。
I want to copy an int
array to another int
array. They use the same define for length so they'll always be of the same length.
What are the pros/cons of the following two alternatives of the size parameter to memcpy()
?
memcpy(dst, src, ARRAY_LENGTH*sizeof(int));
or
memcpy(dst, src, sizeof(dst));
Will the second option always work? Regardless of the content?
One thing that favors the last one is that if the array were to change, it'll be some house-keeping to update the memcpy()
's.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
只要
dst
被声明为一个具有大小的数组,sizeof
就会返回该数组的大小(以字节为单位):如果
dst
碰巧如果是指向此类数组的第一个元素的指针(与数组本身的类型相同),则它将不起作用:As long as
dst
is declared as an array with a size,sizeof
will return the size of that array in bytes:If
dst
just happens to be a pointer to the first element of such an array (which is the same type as the array itself), it wont work:如果使用 malloc 分配,则必须声明数组的大小
如果使用静态数组分配,则可以仅使用
sizeof
If you have allocated using malloc you must state the size of the array
If you have allocated with a static array you can just use
sizeof
仅当
dst
是一个在编译时大小已知的数组时,sizeof(dst)
才是正确的:如int arr[ARRAY_LENGTH]
或 C99可变长度数组;否则它返回指针的大小,而不是目标数组的长度。为了避免将来出现错误,请保持一致并首选第一种形式:类型大小 * 长度。
sizeof(dst)
is correct only ifdst
is an array which size is known at compile time: likeint arr[ARRAY_LENGTH]
or a C99 variable length array; otherwise it returns the size of a pointer, not the length of the destination array.To avoid future bug, be consistent and prefer the first form: size of type * length.
如果您有一个数组(真正的数组),您可以使用 sizeof(array) 技巧,但请注意,如果您重构代码并将其推入数组已退化为指针的位置(或如果内存最初是在指针(malloc/new)中分配的,则需要
忽略源和目标的相对大小,也就是说,假设它们在讨论的其余部分中是相同的。使用 C++ 我会推荐一个元编程技巧,它将为您提供数组的类型安全大小计数,并且如果您尝试将其与指针一起使用,则将无法编译:
这样:
如果在任何时候您重构并且代码移动到以下位置数组已衰减(或者您将静态数组替换为动态分配的数组),编译器会告诉您需要更正大小计算。
If and when you have an array (real one) you can use the
sizeof(array)
trick, but note that if you refactor the code and push it somewhere where the array has decayed into a pointer (or if the memory was initially allocated in a pointer (malloc/new) you will need to pass a known size.Ignoring the relative sizes of source and destination, that is, assuming that they are the same for the rest of the discussion, if you are using C++ I would recommend a metaprogramming trick that will give you a typesafe size count for arrays and will fail to compile if you try to use it with pointers:
That way:
If at any time you refactor and the code moves to a place where the array has decayed (or you replace an static array for a dynamically allocated one) the compiler will tell you that you need to correct the size calculation.
仅当您添加回丢失的
)
并且dst
是静态数组(即类型为int[123] 时,第二个选项才有效)。
如果
dst
的大小未知(即int[]
),则sizeof dst
仅返回指针大小,因为dst
> 已退化为指针。在这种情况下,您需要使用sizeof(*dst)*ARRAY_LENGTH
。The 2nd option works only if you added back the missing
)
anddst
is a static array (i.e. of typeint[123]
).If
dst
has unknown size (i.e.int[]
), thensizeof dst
only returns the pointer size, sincedst
has been decayed to a pointer. In this case, you need to usesizeof(*dst)*ARRAY_LENGTH
.假设 dst 的类型为 int*,sizeof(dst) 将返回指针本身的大小(即 32 位系统上为 4,64 位系统上为 8),因此您的第二个示例将仅复制这么多字节,而第一个将正确使用内容的实际大小。
Assuming dst is of type int*, sizeof(dst) will return the size of the pointer itself (i.e. 4 on a 32 bit system, 8 on a 64 bit system), so your second example will only every copy this many bytes, while the first one will correctly use the actual size of the content.
仅当满足两个条件时它才会起作用:
dst
是常规数组,而不是指针src
和dst
大小相同It will work only if both conditions are satisfied:
dst
is regular array, not pointersrc
anddst
are the same sizesizeof(X) 总是给出“X”的字节数
如果 X 是一个 10 的 uint16_t 数组,那么 sizeof(X) 将返回 20,
如果你想要元素的数量,你必须进行一些字节算术:
8位=1字节
16 位 = 2 字节
32位=4字节
64位=8字节
因此,要获取您可以执行的元素数量:
导致:
当然,您可能希望将 ( sizeof(X)/sizeof(X[0]) ) 设为常量/变量,这样您就不必每次都进行计算。 (我不知道编译器是否会对此进行优化)
sizeof(X) always gives you the NUMBER OF BYTES of "X"
if X is a uint16_t array of 10, then sizeof(X) will return 20
if you want the number of elements you have to do a bit of byte arithmetic:
8bit = 1byte
16bit = 2bytes
32bit = 4 bytes
64bit = 8 bytes
so to get the number of elements you could do:
resulting in:
of course you would probably want to make ( sizeof(X)/sizeof(X[0]) ) a constant/variable so that you don't compute each time.. ( I don't know if compilers will always optimize this)
它应该是源缓冲区大小和目标缓冲区大小之间的最小值。
传统上,使用源缓冲区的大小。有时会溢出目标缓冲区...因此最好使用该函数的“更安全”版本:指定源缓冲区大小和目标缓冲区大小的函数。
您可以通过 ISO/IEC TR24731 获得“更安全”的功能。还有更多内容,例如一致的返回值和一致的字符串处理行为。
“更安全”的函数现在已成为 C 标准的一部分,因此它应该随处可用。所以你应该使用
memcpy_s
。你不能在Linux上使用它,因为它不提供这些功能(不要相信有关标准兼容的营销炒作)。在 Linux 上,您应该“推出自己的”包装器。
并不是每个人都喜欢更安全的功能。例如,请参阅您使用 TR 24731“安全”功能吗? 。我能说的就是:多个 libunp 缓冲区溢出。数以百万计的路由器和网关受到多个漏洞的影响,并且许多尚未修补。它们是由于更安全的功能本来可以阻止的错误造成的。给所有说“不要使用微软这个垃圾”的人+1。
It should be the minimum between the size of the source buffer and the size of the destination buffer.
Traditionally, the size of the source buffer has been used. That overflowed the destination buffer on occasion... So its better to use a "safer" version of the function: one that specifies both the source and destination buffer sizes.
You have "safer" functions available via ISO/IEC TR24731. There's a lot more to it, like consistent return values and consistent string handling behavior.
The "safer" functions are part of the C standard now, so its supposed to be available everywhere. So you should use
memcpy_s
.You can't use it on Linux, because it does not provide the functions (don't believe the marketing hype about standards compliant)). On Linux, you should "roll your own" wrapper.
Not everyone is a fan of the safer functions. See, for example, Do you use the TR 24731 'safe' functions?. About all I can say about that is: Multiple libunp buffer overflows. Millions of routers and gateways are subject to multiple vulnerable and many remain unpatched. And they were due to bugs that would have been stopped by the safer functions. +1 to everyone who is saying "don't use this Microsoft crap".
这取决于。 arr 和指针都是数组,但 sizeof() 仅返回 arr 的正确大小,该大小是在编译时声明的。
It depends. Both arr and pointer are arrays, but sizeof() returns only the correct size for arr, which is declared at compile time.
如果 dst 是从堆分配的(例如使用 malloc),则第二个解决方案将不起作用。 sizeof(dst) 仅当编译器知道时才起作用。例如,以下示例将失败,因为 sizeof(dst) 将等于指针的大小(4-8 字节)。
此代码段每次都会起作用:
If dst was allocated from the heap (using malloc for example) the second solution will not work. sizeof(dst) will only work when it is know to the compiler. For example, the following example will fail as sizeof(dst) will be equal to the sizeof a pointer (4-8 bytes.)
This code segment will work every time: