更改指针类型导致写访问异常

Changing pointer type causes write access exception

我试图弄清楚在缓冲区末尾附近写入一块内存是否会溢出,但我 运行 遇到了一个奇怪的问题,我猜这是由于对如何操作的一些误解指针类型有效。

给定这段代码,它只是分配内存并尝试在它的最后写入:

#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 内存 window 显示可用内存小于 end 计算得出的内存。

我误会了什么?不应该 pointer + size == endOfBuffer,无论使用何种类型?

VirtualAlloc 中的第二个参数是以字节为单位分配的大小。如果你想要一个 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 个字节。

指针算法使用要跳过的元素数,而不是字节数。 int32_t* 加 1 跳过 4 个字节,int16_t* 加 1 跳过 2 个字节。

我不知道为什么 int 大小写对你有用,因为它不应该。