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 memseting 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
Related
i want to transmit data by bit unit so i was access data with char* variable. here is my code.
int main()
{
//initiate int variable and casting with char*
int a = 65;
cout << a << endl;
char* p = reinterpret_cast<char*>(&a);
cout << "------------------" << endl;
//check char* p is pointing &a
cout << &a << endl;
printf("0x%x\n", p);
cout << "------------------" << endl;
//access int variable with byte unit
cout << (int)*(p + 0) << endl;
cout << (int)*(p + 1) << endl;
cout << (int)*(p + 2) << endl;
cout << (int)*(p + 3) << endl;
cout << "------------------" << endl;
//initiate int variable and assemble with char* access in way 1
int* b = new int(0);
*b = *(p + 0) << 24;
*b += *(p + 1) << 16;
*b += *(p + 2) << 8;
*b += *(p + 3);
cout << *b << endl;
cout << "------------------" << endl;
//initiate int variable and assemble with char* access in way 2
*b = *(p + 0);
*b += *(p + 1) << 8;
*b += *(p + 2) << 16;
*b += *(p + 3) << 24;
cout << *b << endl;
return 0;
}
and output like this.
65 -> variable a is 65
------------------
0x61ff04
0x61ff04 -> char* p is pointing right
------------------
65
0
0
0 -> access with byte unit
------------------
1090519040 -> way 1
------------------
65 -> way 2
when i access data by byte unit that first address pointing data shows '65' so i think this system is big endian.
so i thought if i want to transmit 'a' data to variable 'b', then *(p+0) data should be go to first like way 1, but the result isn't right. *(p+0) go at last - way 2, show right value.
in easy way to think, i think i was transmit data in direct memory point to point like this
variable a => variable b
[0x000000] => [0x100000]
[0x000001] => [0x100001]
[0x000002] => [0x100002]
... => ...
i don't know why this happen. is anyone can explain about this?
============================================================================
problem was solved. the system was not big endian. i was mistake it.
when i access data by byte unit that first address pointing data shows '65' so i think this system is big endian.
No, it means it is little endian. The least significant byte is in the lowest address and has the value 65.
With respect to 'transmitting' data between pointers of the same type by copying plain-old-data byte by byte, unless you are going between systems then endianness doesn't matter. It only matters in the interpretation, and ( *(p + 0) << 24 ) | ( *(p + 1) << 16 ) | ( *(p + 2) << 8 ) | *(p + 3) is the big endian interpretation, so gives you the wrong result. You already know that *p is 65*p is 65, so even if you forget which way big or little means, *(p + 0) << 24 will be wrong.
If you do want to transmit between systems byte-by-byte, there are the posix functions hton*X*() and ntoh*X*() which convert different integral types from host to network or from network to host byte order.
I drew this for a better understanding. In the PC's memory there are succesive memory zones with length of 1 byte ( the green ones ). They can be grouped for representing bigger data ( as an int in our example ).
What i want to add to this picture is that the green squares are succesive addresses like 0x000000 followed by 0x000001 etc. Then the addresses from arr are jumping by four like 0x000000 and the next one would be 0x000004 ( because an int in this care is 4bytes ).
The code_1:
int arr[4] = {1,2,3,4};
int *p = arr;
cout << p << endl;
cout << ++p << endl;
cout << ++p << endl;
cout << ++p << endl;
The output_1:
0x69fedc
0x69fee0
0x69fee4
0x69fee8
The code_2:
char arrr[5] = {'1','2','3','4', '\n'};
char *ptr = arrr;
cout << &ptr << endl;
cout << &(++ptr) << endl;
cout << &(++ptr) << endl;
cout << &(++ptr) << endl;
The output_2:
0x69fed0
0x69fed0
0x69fed0
0x69fed0
The problem:I expect in output_2 i expect that the addresses would be 0x69fed0,0x69fed1,0x69fed2,0x69fed4
This is because you are displaying the address of the pointer instead of the address stored in the pointer:
char *ptr = 0;
std::cout << &ptr; // address where the pointer is placed
std::cout << (void*)ptr; // address managed by the pointer = 0
++ptr;
std::cout << &ptr; // this value never changes
std::cout << (void*)ptr; // Now this value should be 1
So while studying for my exams I was trying to do a practice problem for pointers.
In the following code I'm trying to display the number of elements before the first occurrence of 0.
There is only one part that i didn't understand please see the 6th last line.
#include <iostream>
using namespace std;
int main()
{
int A[10];
for (int i = 0; i < 10; i++){
cout << "Please enter number " << i + 1 << " in the array: ";
cin >> A[i];
}
int *Aptr = A;
while(*Aptr !=0){
cout << *Aptr << "";
Aptr++;
}
cout << "\nThere are " << (Aptr - A) //Here is what i don't understand.
<< " numbers before the first occurrence of 0." << endl;
system("pause");
return 0;
}
So why exactly is (Aptr - A) giving me the number of elements instead of a memory location, and why is this even doable since Aptr is a pointer and A is an array?
Can someone explain to me in detail?
When used in an expression, like Aptr - A, the name of an array A will be implicitly converted to a pointer (equal to &A[0]).
Then the compiler is faced with subtracting two pointers of the same type (both of type int * in your case). That is specified as giving a value of type std::ptrdiff_t, which is, in turn "a signed integral type able to represent the result of subtracting two pointers".
Pointer arithmetic, when subtracting two pointers of type int (i.e. two int *s) gives the number of ints between the two pointers (assuming they are in the same object, which is true in this case, since Aptr points at an element of the array A).
Practically, if Aptr is equal to &A[i], the subtraction Aptr - &A[0] gives a std::ptrdiff_t equal to i.
Note: there is another problem in your code, as since the first (for) loop reads 10 values, while the second while loop keeps incrementing Aptr until it points at an int with value 0. If the user enters any zero values, the second loop will stop when it finds the first (even if the user enters non-zero elements after that). If the user enters no values equal to 0, then the while loop has undefined behaviour, since Aptr will keep walking through memory past the end of A until it happens to find memory that compares (as an int) equal to 0.
First of all, name of array A is associated to address of (pointer at) the first item in the array.
So why exactly is (Aptr - A) giving me the number of elements?
Because according to rules address arithmetic subtraction operation (also +, and similar) is performed based on the data type.
I mean, that compiler operating with int* makes ++, --, addition, subtraction an integer, etc. adds addresses needed for shifting to next/previous item.
If you really want to see how many bytes are located between addresses, just convert addresses to int before making subtraction:
cout << endl << "Address difference is " << int(Aptr) - int(A) << endl;
You can try that with different data types as follows:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int A[5];
short B[5];
unsigned char C[5];
cout << "Array (data type) | Syze of array | Size of item | Item distanse | Bytes distance" << endl;
cout << "A (int) :" << setw(10)
<< sizeof(A) << setw(15)
<< sizeof(A[0]) << setw(15)
<< &A[4] - A << setw(15)
<< int(&A[4]) - int(A) << endl;
cout << "B (short) :" << setw(10)
<< sizeof(B) << setw(15)
<< sizeof(B[0]) << setw(15)
<< &B[4] - B << setw(15)
<< int(&B[4]) - int(B) << endl;
cout << "C (un.char) :" << setw(10)
<< sizeof(C) << setw(15)
<< sizeof(C[0]) << setw(15)
<< &C[4] - C << setw(15)
<< int(&C[4]) - int(C) << endl;
system("pause");
return 0;
}
UPDATE
To be better prepared for your exam, consider the following example with pointers:
#include <iostream>
using namespace std;
int main()
{
int A[5] = {0}; // all items now are 0
int * P = A + 2; // the same as P = &A[2];
*P = 33; // writing to item A[2];
cout << A[2] << endl; // just to check in usual way
cout << *(A + 2) << endl; // using A as a pointer
cout << *(2 + A) << endl; // almost the same to previous
cout << 2[A] << endl; // quite strange, but it works
cout << 0[P] << endl; // and this is the same
return 0;
}
You must understand that 0[P] means for compiler *(0 + P), as well as 2[A] means - *(2 + A), but you should not write in your program in such style (exceptions are only cases when you want to confuse a reader).
And one more important thing - difference between array and pointer - are shown in the following example:
int A[] = {1, 2, 3, 4, 5};
int *P = A;
cout << "A = " << A << endl;
cout << "P = " << P << endl;
cout << "size of A = " << sizeof(A) << endl;
cout << "size of P = " << sizeof(P) << endl;
even if the addresses (vaules A and P) are equal, compiler works with array (A) in a different way than with pointer: sizeof(A) means memory allocated for whole array (5 items of sizeof(int) each), but sizeof(P) means memory allocated for data type int * (pointer to int). So, sizeof(P) depends only on compiler and OS platform (e.g. pointer can be 32-bit or 64-bit), but sizeof(A) depends on size of item (int may be not 32 bits) and NUMBER OF ITEMS in the array.
And you can "go to the next item" with pointer:
P++;
cout << *P << endl;
but you are not able to do:
A++;
because A is not variable of pointer type (it is just similar in sense of "address of the first item"), and compiler will say you something like:
error : '++' needs l-value
So here is my code:
cout << "The size of an integer is " << sizeof(int) << endl;
cout << "The size of a double is " << sizeof(double) << endl;
cout << "The size of a string is " << sizeof(string) << endl;
int num = 1234;
cout << "The size of a num is " << sizeof(num) << endl;
int *pnum = #
cout << "The size of a pointer pnum is " << sizeof(pnum) << endl;
cout << "The size of a value pointed at by pnum is " << sizeof(*pnum) << endl;
return 0;
Im confused by this chunk of code because output of this is:
The size of an integer is 4
The size of a double is 8
The size of a string is 40
The size of a num is 4
The size of a pointer pnum is 8
The size of a value pointed at by pnum is 4
I think size of a pointer pnum should be the same like value pointed at by pnum because Im watching a tutorial "Programming C++" and in this tutorial they are the same. Can someone explain why they arent the same in my program?
sizeof(pnum) is exactly the same as sizeof(int*), number of bytes needed to represent a pointer to the int value. Such pointer takes 64 bits at 64-bite system, which is 8 bytes as shown in your code output.
At the same time, sizeof(*pnum) is exactly the same as sizeof(int), since *pnum has type int. This type usualy is 32-bits long, which gives us 4 bytes.
and in this tutorial they are the same:
the reason could be that for that specific machine (like my own 32 bit machine) sizeof(int) = sizeof(int*) = 4.
The reason you get different results is that *pnum is the pointee of pnum which is an int (4 bytes on your machine) and pnum itself is a pointer (8 bytes on your machine)
int a[5];
cout << &a[1] << " " << &a[0] << endl;
cout << (&a[1] - &a[0]);
In the above code, why is &a[1] - &a[0] equal to 1 and not 4? Shouldn't there be 4 bytes between these addresses since we have an int array?
No, pointer difference is in elements, not in bytes.
Pointers are incremented by the size of there type. Reason is because you want to point to the next item. So taking you example further.
int a[5];
int *ptr=&a[0];
// ptr is now pointing at first element.
ptr+3; // now its pointing at 3rd element.
To get it in bytes: (see it live https://ideone.com/CrL4z)
int a[5];
cout << (a+1) << " " << (a+0) << endl;
cout << (reinterpret_cast<char*>(a+1) - reinterpret_cast<char*>(a+0));