free(): 无效的下一个大小 (快速): 0x0000000000f45160 ***.

free(): invalid next size (fast): 0x0000000000f45160 ***

本文关键字:快速 0x0000000000f45160 无效 free 下一个      更新时间:2023-10-16

我已经读到由于释放未分配的指针(例如双重释放指针)而发生的此错误,但在我的情况下,违规行如下所示:

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_bytesdata开始,并写入多个零。该数字是:这个(动态分配的)数组的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的地址来看到这一点。它比 32 字节大 128 字节。

我认为这是因为您在添加后进行投射。 尝试在添加之前进行投射。

static_cast<void*>(data) + prev_bytes