更改指针类型导致写访问异常
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 大小写对你有用,因为它不应该。
我试图弄清楚在缓冲区末尾附近写入一块内存是否会溢出,但我 运行 遇到了一个奇怪的问题,我猜这是由于对如何操作的一些误解指针类型有效。
给定这段代码,它只是分配内存并尝试在它的最后写入:
#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 大小写对你有用,因为它不应该。