我试图弄清楚在缓冲区末端附近写一块内存是否会溢出,但是我遇到了一个奇怪的问题,我想这是由于对类型的错误有些误解指针工作。
鉴于此代码,它只分配内存并尝试在其末尾写入:
#include <Windows.h>
#include <stdint.h>
int main() {
size_t size = 19200;
int16_t* start = (int16_t*) VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
int16_t* end = start + size;
int16_t* writeToEnd = end - sizeof(int16_t);
*writeToEnd = 1;
return 0;
}
我在writeToEnd
收到了非法的写入异常。但是,如果我将所有内容更改为int
:
#include <Windows.h>
#include <stdint.h>
int main() {
size_t size = 19200;
int* start = (int*) VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
int* end = start + size;
int* writeToEnd = end - sizeof(int);
*writeToEnd = 1;
return 0;
}
一切正常。我会理解,如果某些值会导致int16_t
- 类型溢出,但通过手动检查所有值,一切似乎都可以。
Visual Studio内存窗口显示可用内存小于end
计算到的内容。
我误解了什么?无论使用何种类型,都不应该pointer + size == endOfBuffer
吗?
答案 0 :(得分:1)
VirtualAlloc中的第二个参数是要在 bytes 中分配的大小。如果你想要一个19200 16位整数的数组,你应该调用它
int16_t* start = (int16_t*) VirtualAlloc(0, size*sizeof(int16_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
然后下一行就可以了:
int16_t *end = start + size;
在这里你实际上是
int16_t *end = &start[size];
在开始之前是19200 * 2字节。
指针算术使用要跳过的元素数,而不是字节数。将1添加到int32_t *跳过4个字节,将1添加到int16_t *跳过2个字节。
我不知道为什么int case适合你,因为它不应该。