int main()
{
int arr[][3]={{1,2},{3,4},{4,5}};
int (*p)[3];
p=arr;
cout<<sizeof(p)<<" "<<sizeof(*p);
return 0;
}
Above is my code,the output of this code is 4 12.So my doubt is what do the complier interpret p and *p as ? what they are actually pointing to?
P is a pointer, you probably have a 32-bit system, therefore sizeof(p) returns 4.
Then you defined p as a pointer to an array of 3 ints, the sizeof int is 4, so the sizeof what it's pointing to, sizeof(*p) is 12.
Related
int main()
{
int arr[]={2,3,5,6,8};
int *ptr;
ptr=&arr[3];
cout<<ptr-arr;
}
Q.why the answer is 3 after compiling the code i.e. as it should be 3*sizeof(int) which in this case should be 3*4=12?
When you subtract pointers you get the distance between them, not the allocated size. The same goes for iterators in STL.
https://en.cppreference.com/w/cpp/language/operator_arithmetic#Additive_operators
The reason is that it is much easier to write correct code.
When the pointer difference between consecutive elements of an array is 1, then you can use ++p to walk through the array (assuming p is a pointer to an element). For example:
int a[10];
for (auto p = a, e = a + 10; p != e; ++p)
*p = 42;
Notice how the code does not have to deal with the size of the elements. If the array type changes from int to double, the code does not have to change and is still correct.
#include<stdio.h>
int main(){
int a, b, c;
char *p = 0;
int *q = 0;
double *r = 0;
cout<<(int)(p + 1); // printing 1 char size
cout<<(int)(q + 1); // printing 4
cout<<(int)(r + 1); // printing 8
int y = 9;
int *u = &y;
cout<<(int)(u+1); //printing 7208688
cout<<*(p+1); //not able to dereferance
}
How is type-casting working in both the above case?
Why pointers p, q, r are unable to dereference?
Dereferencing any of p, q, r, p + 1, q + 1, r + 1 or u + 1 has undefined behaviour, because none of those pointers point to objects of the correct type.
You can add to a pointer, to get a different pointer value. This is only defined for results that stay within the same array, plus the "one-past-the-end" pointer value (treating a pointer to a single object as an array of length one). You can also convert a pointer to an integer type, to get an implementation defined value. Doing those things does not involve dereferencing the pointer.
Adding to a null pointer is also undefined behaviour, because the null pointer does not point to an object, there is nothing to be "one-past-the-end" of.
I implemented an insertion sort in C and someone who was helping me told my make something a pointer, as shown in the following line near the end, but why?
size_t size = sizeof( array ) / sizeof( *array );
Why is the second one a pointer to array, and what does size_t do?
sizeof(array) = size, in bytes, of the entire array;
sizeof(*array) = size, in bytes, of the first item in the array;
As items in a C array are of uniform size, dividing the first by the second gives the number of items in the array.
size_t is an unsigned integer large enough to store the size of any item the computer dan store in memory. So, usually, it's the same as an unsigned int, but it's not guaranteed to be and there's semantic value in it being a different thing.
Why is the second one a pointer to array
Example 1
char a[5];
sizeof(a)=5
sizeof(*a)=1
So, size = 5/1 = 5 // this indicates the no of elements in the array
Example 2
int a[5];
sizeof(a)= 20
sizeof(*a)=4
So, size = 20/4 = 5 // this indicates the no of elements in the array
and what does size_t do?
Read: What is size_t in C?
What would be a declaration likechar *song;
What does the * does? Is it an array, a pointer or something else?
The * (Asterisk) indicates the variable is a pointer. As for a small example:
int x = 0;
int *y = &x; //y is pointing to x
const char* myText = "Text";
You might however be interested in learning a bit more about what pointers are.
H2CO3 is right, you should read up on c, and pointers.
char *song = "smb:d=4,o=5,b=......."
Is the does the same thing as the code below
char song[] = "smb:d=4,o=5,b=......."
In both cases song is a pointer to an array of strings. C++ has a string object, but plain C used c_strings. A c_string is simply a char array. You have what looks like a c_string.
*song //the same as "song[0]" will equal 's'
*(song+1) //the same as "song[1]" will equal 'm'
*(song+2) //the same as "song[2]" will equal 'b'
and so on
I am confused by the behavior of pointer arithmetics in C++. I have an array and I want to go N elements forward from the current one. Since in C++ pointer is memory address in BYTES, it seemed logical to me that the code would be newaddr = curaddr + N * sizeof(mytype). It produced errors though; later I found that with newaddr = curaddr + N everything works correctly. Why so? Should it really be address + N instead of address + N * sizeof?
Part of my code where I noticed it (2D array with all memory allocated as one chunk):
// creating pointers to the beginning of each line
if((Content = (int **)malloc(_Height * sizeof(int *))) != NULL)
{
// allocating a single memory chunk for the whole array
if((Content[0] = (int *)malloc(_Width * _Height * sizeof(int))) != NULL)
{
// setting up line pointers' values
int * LineAddress = Content[0];
int Step = _Width * sizeof(int); // <-- this gives errors, just "_Width" is ok
for(int i=0; i<_Height; ++i)
{
Content[i] = LineAddress; // faster than
LineAddress += Step; // Content[i] = Content[0] + i * Step;
}
// everything went ok, setting Width and Height values now
Width = _Width;
Height = _Height;
// success
return 1;
}
else
{
// insufficient memory available
// need to delete line pointers
free(Content);
return 0;
}
}
else
{
// insufficient memory available
return 0;
}
Your error in reasoning is right here: "Since in C++ pointer is memory address in BYTES, [...]".
A C/C++ pointer is not a memory address in bytes. Sure, it is represented by a memory address, but you have to differentiate between a pointer type and its representation. The operation "+" is defined for a type, not for its representation. Therefore, when it is called one the type int *, it respects the semantics of this type. Therefore, + 1 on an int * type will advance the pointer as much bytes as the underlying int type representation uses.
You can of course cast your pointer like this: (int)myPointer. Now you have a numeric type (instead of a pointer type), where + 1 will work as you would expect from a numeric type. Note that after this cast, the representation stays the same, but the type changes.
A "pointer" points to a location.
When you "increment", you want to go to the next, adjacent location.
Q: "Next" and "adjacent" depend on the size of the object you're pointing to, don't they?
Q: When you don't use "sizeof()", everything works, correct? Why? What do you think the compiler is doing for you, "behind your back"?
Q: What do you think should happen if you add your own "sizeof()"?
ON TOP OF the "everything works" scenario?
pointers point to addresses, so incrementing the pointer p by N will point to the Nth block of memory from p.
Now, if you were using addresses instead of pointers to addresses, then it would be appropriate to add N*sizeof(type).