memcpy(),size参数的值应该是多少?

发布于 2024-08-29 19:59:09 字数 361 浏览 8 评论 0原文

我想将一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

深海夜未眠 2024-09-05 19:59:09

只要 dst 被声明为一个具有大小的数组,sizeof 就会返回该数组的大小(以字节为单位):

int dst[ARRAY_LENGTH];

memcpy( dst, src, sizeof(dst) ); // Good, sizeof(dst) returns sizeof(int) * ARRAY_LENGTH

如果 dst 碰巧如果是指向此类数组的第一个元素的指针(与数组本身的类型相同),则它将不起作用:

int buffer[ARRAY_LENGTH];
int* dst = &buffer[0];

memcpy( dst, src, sizeof(dst) ); // Bad, sizeof(dst) returns sizeof(int*)

As long as dst is declared as an array with a size, sizeof will return the size of that array in bytes:

int dst[ARRAY_LENGTH];

memcpy( dst, src, sizeof(dst) ); // Good, sizeof(dst) returns sizeof(int) * ARRAY_LENGTH

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:

int buffer[ARRAY_LENGTH];
int* dst = &buffer[0];

memcpy( dst, src, sizeof(dst) ); // Bad, sizeof(dst) returns sizeof(int*)
木緿 2024-09-05 19:59:09

如果使用 malloc 分配,则必须声明数组的大小

int * src = malloc(ARRAY_LENGTH*sizeof(*src));
int * dst1 = malloc(ARRAY_LENGTH*sizeof(*dst1));
memcpy(dst1,src,ARRAY_LENGTH*sizeof(*dst1));

如果使用静态数组分配,则可以仅使用 sizeof

int dst2[ARRAY_LENGTH];
memcpy(dst2,src,sizeof(dst2));

If you have allocated using malloc you must state the size of the array

int * src = malloc(ARRAY_LENGTH*sizeof(*src));
int * dst1 = malloc(ARRAY_LENGTH*sizeof(*dst1));
memcpy(dst1,src,ARRAY_LENGTH*sizeof(*dst1));

If you have allocated with a static array you can just use sizeof

int dst2[ARRAY_LENGTH];
memcpy(dst2,src,sizeof(dst2));
橘虞初梦 2024-09-05 19:59:09

仅当 dst 是一个在编译时大小已知的数组时,sizeof(dst) 才是正确的:如 int arr[ARRAY_LENGTH] 或 C99可变长度数组;否则它返回指针的大小,而不是目标数组的长度。

为了避免将来出现错误,请保持一致并首选第一种形式:类型大小 * 长度。

sizeof(dst) is correct only if dst is an array which size is known at compile time: like int 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.

眼趣 2024-09-05 19:59:09

如果您有一个数组(真正的数组),您可以使用 sizeof(array) 技巧,但请注意,如果您重构代码并将其推入数组已退化为指针的位置(或如果内存最初是在指针(malloc/new)中分配的,则需要

忽略源和目标的相对大小,也就是说,假设它们在讨论的其余部分中是相同的。使用 C++ 我会推荐一个元编程技巧,它将为您提供数组的类型安全大小计数,并且如果您尝试将其与指针一起使用,则将无法编译:

template <typename T, int N>
inline int array_memory_size( T (&a)[N] ) { return sizeof a; }

这样:

int main() {
   int array[10];
   int *ptr = array;
   int orig[10] = { 0 };
   memcpy( array, orig, array_memory_size(array) ); // ok
   //memcpy( ptr, orig, array_memory_size(ptr) ); // compilation error
}

如果在任何时候您重构并且代码移动到以下位置数组已衰减(或者您将静态数组替换为动态分配的数组),编译器会告诉您需要更正大小计算。

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:

template <typename T, int N>
inline int array_memory_size( T (&a)[N] ) { return sizeof a; }

That way:

int main() {
   int array[10];
   int *ptr = array;
   int orig[10] = { 0 };
   memcpy( array, orig, array_memory_size(array) ); // ok
   //memcpy( ptr, orig, array_memory_size(ptr) ); // compilation error
}

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.

渡你暖光 2024-09-05 19:59:09

第二个选项总是有效吗?与内容无关?

仅当您添加回丢失的 ) 并且 dst 是静态数组(即类型为 int[123] 时,第二个选项才有效)。

如果dst的大小未知(即int[]),则sizeof dst仅返回指针大小,因为dst > 已退化为指针。在这种情况下,您需要使用sizeof(*dst)*ARRAY_LENGTH

Will the second option always work? Regardless of the content?

The 2nd option works only if you added back the missing ) and dst is a static array (i.e. of type int[123]).

If dst has unknown size (i.e. int[]), then sizeof dst only returns the pointer size, since dst has been decayed to a pointer. In this case, you need to use sizeof(*dst)*ARRAY_LENGTH.

り繁华旳梦境 2024-09-05 19:59:09

假设 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.

亽野灬性zι浪 2024-09-05 19:59:09

第二个选项总是有效吗?与内容无关?

仅当满足两个条件时它才会起作用:

  • dst是常规数组,而不是指针
  • srcdst大小相同

Will the second option always work? Regardless of the content?

It will work only if both conditions are satisfied:

  • dst is regular array, not pointer
  • src and dst are the same size
小嗲 2024-09-05 19:59:09

sizeof(X) 总是给出“X”的字节数
如果 X 是一个 10 的 uint16_t 数组,那么 sizeof(X) 将返回 20,

uint16_t X[10]={0};
cout<<"sizeof x: "<<sizeof(X);

gt; sizeof x: 20

如果你想要元素的数量,你必须进行一些字节算术:

8位=1字节
16 位 = 2 字节
32位=4字节
64位=8字节

因此,要获取您可以执行的元素数量:

 numb_of_elements = ( sizeof(X)/sizeof(X[0]) );

导致:

uint32_t source[100]={0};
memcpy((void*) dest, (void*) source, ( sizeof(source)/sizeof(source[0]) ));

当然,您可能希望将 ( 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

uint16_t X[10]={0};
cout<<"sizeof x: "<<sizeof(X);

gt; sizeof x: 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:

 numb_of_elements = ( sizeof(X)/sizeof(X[0]) );

resulting in:

uint32_t source[100]={0};
memcpy((void*) dest, (void*) source, ( sizeof(source)/sizeof(source[0]) ));

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)

安稳善良 2024-09-05 19:59:09

memcpy(),size参数的值应该是多少?

它应该是源缓冲区大小和目标缓冲区大小之间的最小值。

传统上,使用源缓冲区的大小。有时会溢出目标缓冲区...因此最好使用该函数的“更安全”版本:指定源缓冲区大小和目标缓冲区大小的函数。

您可以通过 ISO/IEC TR24731 获得“更安全”的功能。还有更多内容,例如一致的返回值和一致的字符串处理行为。

“更安全”的函数现在已成为 C 标准的一部分,因此它应该随处可用。所以你应该使用memcpy_s

你不能在Linux上使用它,因为它不提供这些功能(不要相信有关标准兼容的营销炒作)。在 Linux 上,您应该“推出自己的”包装器。

并不是每个人都喜欢更安全的功能。例如,请参阅您使用 TR 24731“安全”功能吗? 。我能说的就是:多个 libunp 缓冲区溢出。数以百万计的路由器和网关受到多个漏洞的影响,并且许多尚未修补。它们是由于更安全的功能本来可以阻止的错误造成的。给所有说“不要使用微软这个垃圾”的人+1。

memcpy(), what should the value of the size parameter be?

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".

陈年往事 2024-09-05 19:59:09

这取决于。 arr 和指针都是数组,但 sizeof() 仅返回 arr 的正确大小,该大小是在编译时声明的。

int main() {
        int arr[10];
        int * pointer;
        pointer = (int *) malloc(10 * sizeof(int));
        printf("%d\n", sizeof(arr)); // 40
        printf("%d\n", sizeof(pointer)); // 4 or 8
        free(pointer);
}

It depends. Both arr and pointer are arrays, but sizeof() returns only the correct size for arr, which is declared at compile time.

int main() {
        int arr[10];
        int * pointer;
        pointer = (int *) malloc(10 * sizeof(int));
        printf("%d\n", sizeof(arr)); // 40
        printf("%d\n", sizeof(pointer)); // 4 or 8
        free(pointer);
}
半葬歌 2024-09-05 19:59:09

如果 dst 是从堆分配的(例如使用 malloc),则第二个解决方案将不起作用。 sizeof(dst) 仅当编译器知道时才起作用。例如,以下示例将失败,因为 sizeof(dst) 将等于指针的大小(4-8 字节)。

#define ARRAY_LENGTH 10
int *dst;

dst = malloc(ARRAY_LENGTH*sizeof(int));
memcpy(dst, src, sizeof(dst)); // sizeof dst in this case would be 4 bytes on 32 bit system

此代码段每次都会起作用:

#define ARRAY_LENGTH 10
int *dst;

dst = malloc(ARRAY_LENGTH*sizeof(int));
memcpy(dst, src, ARRAY_LENGTH*sizeof(int)); // sizeof would be 40 bytes

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.)

#define ARRAY_LENGTH 10
int *dst;

dst = malloc(ARRAY_LENGTH*sizeof(int));
memcpy(dst, src, sizeof(dst)); // sizeof dst in this case would be 4 bytes on 32 bit system

This code segment will work every time:

#define ARRAY_LENGTH 10
int *dst;

dst = malloc(ARRAY_LENGTH*sizeof(int));
memcpy(dst, src, ARRAY_LENGTH*sizeof(int)); // sizeof would be 40 bytes
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文