I've read about this error occurring due to freeing a non-allocated pointer (e.g. double-freeing a pointer) but in my case the offending line looks like this:
memset(data + prev_bytes, 0, sizeof(int) * size - prev_bytes);
When I comment this out, the error goes away. So, I figure I must be writing past the buffer I allocated, but I don't see how. I added some debugging output before the offending line, like so:
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);
And the output is:
> 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 ***
To give a little context, data
is an array of integers, and I want to keep the first prev_bytes
of this array intact, while clearing the rest, i.e. setting to zeroes.
To achieve this, I'm memset
ing starting at the data
pointer offset by prev_bytes
, and writing a number of zeroes. That number being: the size
of this (dynamically allocated) array, multiplied by sizeof(int)
(presumably 4 bytes), minus prev_bytes
.
I just don't see how I could be writing past what I've allocated. In case more code is needed, here's the full functions. It just extends an array to double its size.
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);
}
The array data
is treated as an array of integers. By using pointer arithmetic data + prev_bytes
is actually being interepreted as data + prev_bytes * sizeof(int)
and you overflow the buffer.
You can see that by comparing the address of data
with the address of data + prev_bytes
. It's 128 bytes greater, instead of 32.
I think it's because you are casting after you add. Try instead to cast before you add.
static_cast<void*>(data) + prev_bytes