免费():无效的下一个大小(快速):0x0000000000f45160 ***
free(): invalid next size (fast): 0x0000000000f45160 ***
我读到过由于释放未分配的指针(例如双重释放指针)而发生的错误,但在我的例子中,有问题的行如下所示:
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
当我注释掉它时,错误消失了。所以,我想我一定是在写超过我分配的缓冲区,但我不知道如何。我在有问题的行之前添加了一些调试输出,如下所示:
cout << "> address of `data`: " << static_cast<void*>(data) << endl;
cout << "> `prev_bytes`: " << prev_bytes << endl;
cout << "> address at `data + prev_bytes`: " << static_cast<void*>(data + prev_bytes) << endl;
cout << "> `size`: " << size << endl;
cout << "> `sizeof(int) * size - prev_bytes`: " << (sizeof(int) * size - prev_bytes) << endl;
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
输出为:
> address of `data`: 0xf450f0
> `prev_bytes`: 32
> address at `data + prev_bytes`: 0xf45170
> `size`: 16
> `sizeof(int) * size - prev_bytes`: 32
free(): invalid next size (fast): 0x0000000000f45160 ***
为了提供一点上下文,data
是一个整数数组,我想保持这个数组的第一个 prev_bytes
完整,同时清除其余部分, 即 设置为零。
为了实现这一点,我 memset
从偏移 prev_bytes
的 data
指针开始,并写入一些零。这个数字是:这个(动态分配的)数组的 size
,乘以 sizeof(int)
(大概是 4 个字节),减去 prev_bytes
.
我只是不明白我怎么能写超过我分配的内容。如果需要更多代码,这里是完整的功能。它只是扩展一个数组使其大小加倍。
void extend(int*& data, int& size, int& used) {
int resize_factor = 2;
int* new_buffer = new int[size * resize_factor];
int prev_bytes = sizeof(int) * size;
memcpy(new_buffer, data, prev_bytes);
delete [] data;
data = new_buffer;
size *= resize_factor;
cout << "> address of `data`: " << static_cast<void*>(data) << endl;
cout << "> `prev_bytes`: " << prev_bytes << endl;
cout << "> address at `data + prev_bytes`: " << static_cast<void*>(data + prev_bytes) << endl;
cout << "> `size`: " << size << endl;
cout << "> `sizeof(int) * size - prev_bytes`: " << (sizeof(int) * size - prev_bytes) << endl;
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
}
数组data
被视为整数数组。通过使用指针算法 data + prev_bytes
实际上被解释为 data + prev_bytes * sizeof(int)
并且您溢出了缓冲区。
你可以通过比较data
的地址和data + prev_bytes
的地址看出。它多了 128 个字节,而不是 32 个。
我认为这是因为你在添加后进行转换。尝试在添加之前进行转换。
static_cast<void*>(data) + prev_bytes
我读到过由于释放未分配的指针(例如双重释放指针)而发生的错误,但在我的例子中,有问题的行如下所示:
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
当我注释掉它时,错误消失了。所以,我想我一定是在写超过我分配的缓冲区,但我不知道如何。我在有问题的行之前添加了一些调试输出,如下所示:
cout << "> address of `data`: " << static_cast<void*>(data) << endl;
cout << "> `prev_bytes`: " << prev_bytes << endl;
cout << "> address at `data + prev_bytes`: " << static_cast<void*>(data + prev_bytes) << endl;
cout << "> `size`: " << size << endl;
cout << "> `sizeof(int) * size - prev_bytes`: " << (sizeof(int) * size - prev_bytes) << endl;
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
输出为:
> address of `data`: 0xf450f0
> `prev_bytes`: 32
> address at `data + prev_bytes`: 0xf45170
> `size`: 16
> `sizeof(int) * size - prev_bytes`: 32
free(): invalid next size (fast): 0x0000000000f45160 ***
为了提供一点上下文,data
是一个整数数组,我想保持这个数组的第一个 prev_bytes
完整,同时清除其余部分, 即 设置为零。
为了实现这一点,我 memset
从偏移 prev_bytes
的 data
指针开始,并写入一些零。这个数字是:这个(动态分配的)数组的 size
,乘以 sizeof(int)
(大概是 4 个字节),减去 prev_bytes
.
我只是不明白我怎么能写超过我分配的内容。如果需要更多代码,这里是完整的功能。它只是扩展一个数组使其大小加倍。
void extend(int*& data, int& size, int& used) {
int resize_factor = 2;
int* new_buffer = new int[size * resize_factor];
int prev_bytes = sizeof(int) * size;
memcpy(new_buffer, data, prev_bytes);
delete [] data;
data = new_buffer;
size *= resize_factor;
cout << "> address of `data`: " << static_cast<void*>(data) << endl;
cout << "> `prev_bytes`: " << prev_bytes << endl;
cout << "> address at `data + prev_bytes`: " << static_cast<void*>(data + prev_bytes) << endl;
cout << "> `size`: " << size << endl;
cout << "> `sizeof(int) * size - prev_bytes`: " << (sizeof(int) * size - prev_bytes) << endl;
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
}
数组data
被视为整数数组。通过使用指针算法 data + prev_bytes
实际上被解释为 data + prev_bytes * sizeof(int)
并且您溢出了缓冲区。
你可以通过比较data
的地址和data + prev_bytes
的地址看出。它多了 128 个字节,而不是 32 个。
我认为这是因为你在添加后进行转换。尝试在添加之前进行转换。
static_cast<void*>(data) + prev_bytes