调用 memcpy 并将 num 设置为比需要更多的字节

calling memcpy with num set to more bytes than needed

考虑以下 C 代码:

#define SIZE_A // >= SIZE_B
#define SIZE_B 
#define SOME_SIZE // > SIZE_B

int main() {
    int a[SIZE_A];
    int b[SIZE_B] = {0};
    memcpy(a, b, sizeof(int)*(SOME_SIZE));
    return 0;
}

假设 SIZE_A、SIZE_B 是一些整数并且 SOME_SIZE > SIZE_B 和 SIZE_A>=SIZE_B。 如果发生什么后果:

a. SOME_SIZE < SIZE_A
b. SOME_SIZE = SIZE_A
c. SOME_SIZE > SIZE_A

我试图 运行 它有一些值,但不明白是否有任何恒常性。 谢谢

在您的情况下(因为您正在从 ab 的起始地址复制和复制到 b 的起始地址),它必须保持 SOME_SIZE <= SIZE_A AND SOME_SIZE <= SIZE_B 否则就是 undefined behaviour.

简单来说,从源复制到目标的字节数绝不能比从源 和 [=28= 开始的可用字节多 ] 您指定给 memcpy 的目标地址。例如,如果在你的情况下你要从数组 b 的中间复制,你将不得不进一步缩小 SOME_SIZE 的范围 - 因为从 b 的中间开始有比 SIZE_B.

可用的字节数更少

您正在从 b 变量之后复制数据,在这种情况下,将是随机堆栈内容。您不会看到任何恒定性,因为它是未定义的。好消息(或坏消息,取决于你如何看待它)是它到目前为止还没有崩溃。如果您的 SOME_SIZE 很大,那么我认为您可能会在某些平台上崩溃。

您只能从您已声明的区域复制到您已声明的区域。这意味着一旦 SOME_SIZE > SIZE_B 你调用未定义的行为。

现在常见的实现会发生什么:

a-b) SOME_SIZE <= SIZE_A :如果你没有达到段限制,这意味着尝试从不可读内存中读取,你将在 [= 的内容之后将垃圾复制到 a 的末尾13=] - 但是如果你掉进了不可读的内存中,你会得到一个内存违规信号。

c)SOME_SIZE > SIZE_A:除了读取未定义内存的问题,你把它写在你不知道的地方。这里很可能会发生非常糟糕的事情:

  • 你可以覆盖变量
  • 你可以破坏堆栈中的 return 个地址
  • 您可以尝试访问不可写内存并获得内存违规信号

TL/DR:因为它本质上是未定义的行为,所以会发生什么,嗯,undefined