调用 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
我试图 运行 它有一些值,但不明白是否有任何恒常性。
谢谢
在您的情况下(因为您正在从 a
和 b
的起始地址复制和复制到 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
考虑以下 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
我试图 运行 它有一些值,但不明白是否有任何恒常性。 谢谢
在您的情况下(因为您正在从 a
和 b
的起始地址复制和复制到 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