Why is
int *a = new int[10];
written as
int *a;
a = new int[10];
instead of
int *a;
*a = new int[10];
?
The way I see it, in the second block of code you're saying a, which was a pointer variable, is now an array. In the third block of code you're saying the thing a points to is now an array. Why does the second make more sense than the third?
new int[10] returns a pointer to the first element in the array (which is of type int*). It does not return a pointer to the array (which would be of type int(*)[10]).
a = new int[10] means make a point to the first element of the dynamically allocated array. *a is not a pointer at all. It is the object pointed to by the pointer a (which is of type int).
Note that if you actually had a named array object, the syntax would still be the same:
int x[10];
int* a = x;
Why? In C++, in most cases, whenever you use an array, it is implicitly converted to a pointer to its initial element. So here, int* a = x is the same as int* a = &x[0];.
(There are several cases where the array-to-pointer decay does not occur, most notably when the array is the operand of the & or sizeof operators; they allow you to get the address of the array and the size of the array, respectively.)
*a = ... means assign value to memory that I'm pointing to
a = ... means assign me new memory address that I should point to
The type int* is a pointer to an int. If you apply the derefence operator to such a pointer, you get an int (or, more precisely, actually a reference to an int, i.e. a int&) That is, when you write
int* a;
*a = new int[10]; // ERROR: incompatible types `int&` and `int*`
you try to assign the result of new int[10] which is of type int* to an object of type int&. This isn't supposed to work.
In the third block of code you're saying the thing a points to is now an array.
You're not, though.
new doesn't evaluate to an array, but to a pointer to a block of memory. That's why you're assigning to a pointer.
It's a consequence of dynamically-allocated objects not being directly reachable in the current lexical scope.
Because this :
a = new int[10];
and this :
*a = new int[10];
are completely different things. The 2nd is the pointer dereferencing.
This:
int *a = new int[10];
and this
int *a;
a = new int[10];
are same things.
You are assigning to a pointer variable, so you have to write a.
Would you have written
int* a = new int[10];
this would be more obvious that the type of a is int* (pointer to an `int).
Because operator new returns the address of the object(s) it creates. *a is not an address, it's the int that a points at.
When you declare a pointer,
int *a;
in the memory:
Memory Address Variable Identifier Variable Value
-------------- -------------- --------------
0xAE934904 a ?
When you create a dynamic array, you have 10 integer numbers:
a = new int[10];
Memory Address Variable Identifier Variable Value
-------------- -------------- --------------
0xH3948300 - ?
0xH3948304 - ?
0xH3948308 - ?
0xH394830C - ?
...
(in total, 10 integers) and value of a becomes 0xH3948300.
Memory Address Variable Identifier Variable Value
-------------- -------------- --------------
0xAE934904 a 0xH3948300
On the other hand, if you write *a = new int[10]; this is *(?) which means go to the value that is stored at memory location ?. *(?) is probably not a memory space where you can store memory address. If you want to assign a value to the pointer, you simply type the identifier name, a.
Related
I'm new to programming and I'm trying to wrap my head around the idea of 'pointers'.
int main()
{
int x = 5;
int *pointerToInteger = & x;
cout<<pointerToInteger;
}
Why is it that when I cout << pointerToInteger; the output is a hexdecimal value, BUT when I use cout << *pointerToInteger; the output is 5 ( x=5).
* has different meaning depending on the context.
Declaration of a pointer
int* ap; // It defines ap to be a pointer to an int.
void foo(int* p); // Declares function foo.
// foo expects a pointer to an int as an argument.
Dereference a pointer in an expression.
int i = 0;
int* ap = &i; // ap points to i
*ap = 10; // Indirectly sets the value of i to 10
A multiplication operator.
int i = 10*20; // Needs no explanation.
One way to look at it, is that the variable in your source/code, say
int a=0;
Makes the 'int a' refer to a value in memory, 0. If we make a new variable, this time a (potentially smaller) "int pointer", int *, and have it point to the &a (address of a)
int*p_a=&a; //(`p_a` meaning pointer to `a` see Hungarian notation)
Hungarian notation wiki
we get p_a that points to what the value &a is. Your talking about what is at the address of a now tho, and the *p_a is a pointer to whatever is at the &a (address of a).
This has uses when you want to modify a value in memory, without creating a duplicate container.
p_a itself has a footprint in memory however (potentially smaller than a itself) and when you cout<<p_a<<endl; you will write whatever the pointer address is, not whats there. *p_a however will be &a.
p_a is normally smaller than a itself, since its just a pointer to memory and not the value itself. Does that make sense? A vector of pointers will be easier to manage than a vector of values, but they will do the same thing in many regards.
If you declare a variable of some type, then you can also declare another variable pointing to it.
For example:
int a;
int* b = &a;
So in essence, for each basic type, we also have a corresponding pointer type.
For example: short and short*.
There are two ways to "look at" variable b (that's what probably confuses most beginners):
You can consider b as a variable of type int*.
You can consider *b as a variable of type int.
Hence, some people would declare int* b, whereas others would declare int *b.
But the fact of the matter is that these two declarations are identical (the spaces are meaningless).
You can use either b as a pointer to an integer value, or *b as the actual pointed integer value.
You can get (read) the pointed value: int c = *b.
And you can set (write) the pointed value: *b = 5.
A pointer can point to any memory address, and not only to the address of some variable that you have previously declared. However, you must be careful when using pointers in order to get or set the value located at the pointed memory address.
For example:
int* a = (int*)0x8000000;
Here, we have variable a pointing to memory address 0x8000000.
If this memory address is not mapped within the memory space of your program, then any read or write operation using *a will most likely cause your program to crash, due to a memory access violation.
You can safely change the value of a, but you should be very careful changing the value of *a.
yes the asterisk * have different meanings while declaring a pointer variable and while accessing data through pointer variable. for e.g
int input = 7;
int *i_ptr = &input;/*Here * indicates that i_ptr is a pointer variable
Also address is assigned to i_ptr, not to *iptr*/
cout<<*i_ptr;/* now this * is fetch the data from assigned address */
cout<<i_ptr;/*it prints address */
for e.g if you declare like int *ptr = 7; its wrong(not an error) as pointers ptr expects valid address but you provided constant(7). upto declaration it's okay but when you go for dereferencing it like *ptr it gives problem because it doesn't know what is that data/value at 7 location. So Its always advisable to assign pointers variable with valid addresses. for e.g
int input = 7;
int *i_ptr = &input;
cout<<*i_ptr;
for example
char *ptr = "Hello"; => here * is just to inform the compiler that ptr is a pointer variable not normal one &
Hello is a char array i.e valid address, so this syntax is okay. Now you can do
if(*ptr == 'H') {
/*....*/
}
else {
/*.... */
}
I want to know the statement below is not valid,
int* p;
*p = 3;
but this statement below is
int* p; int a;
a = 9;
p = &a;
*p = 3;
Why cannot I give *p a value before giving it an address but can give it after assigning an address. Thanks
A pointer is just a special type of variable that holds a memory address as its value. Before being initialized, it could possibly point to any random memory address.
Dereferencing a pointer (using the *p = 3 syntax) is telling the computer to go to the memory address pointed to by p, and store the value 3 in that location.
So it should be obvious that without a valid memory location, this is problematic. Here's one possible way of obtaining a valid memory address via allocation:
int *p = new int;
*p = 3;
The first line does two things: 1) allocates memory on the heap for an int, and 2) sets the value of pointer p to the address of the allocated memory.
Without being initialized to point to an address, a pointer will contain some trash address, which is what you attempt to write to in the first example. To be valid, it is essential that the pointer references some valid memory that you own, which requires that you set it to an address.
Can anyone explain the difference between the following two forms and what does each do:
int *p = new int[5];
and
int *p = new int(5);
Query
1) What are we allocating in both the cases i.e either integer or array ??
2) What will be the initial value after allocation in both cases??
3) And reference from where i can found about this
The syntax of a new-expression is as follows:
the keyword new
optional arguments, enclosed in parentheses
type
optional initializer
In new int[5], the type is int[5] and there is no initializer. Thus, an array of 5 ints is allocated, they are not initialized, and a pointer to the first element is returned.
In new int(5), the type is int and the initializer is (5), so one int is allocated, it is initialized with the value 5 (just like in int x(5);), and a pointer to it is returned.
int *p = new int[5];
allocates an "array" of integers with length 5. It returns a pointer to the beginning of 5 contiguous memory blocks, each of which can hold an int.
int *p = new int(5);
allocates a pointer to a single integer initialized to the value 5.
In the first instance it allocates a integer array of size 5. In this case, the elements in the array are uninitialized.
In the second instance it allocates one integer with value 5.
References:
http://www.cplusplus.com/reference/new/operator%20new/
http://www.cplusplus.com/reference/new/operator%20new[]/
here I will answer all questions one by one
Question 1:What are we allocating in both the cases i.e either integer or array ??
int *p = new int[5]; // you are allocating an array
int *p = new int(5); // you are allocating an integer
Question 2:What will be the initial value after allocation in both cases?
int *p = new int[5]; // Initially there will be random value on all indexes
int *p = new int(5); // Initially value will be 5
Question 3:And reference from where i can found about this?
Check the following links
http://www.cplusplus.com/doc/tutorial/dynamic/
http://en.wikipedia.org/wiki/Initialization_%28programming%29
Square brackets are used to denoting arrays of its elements.
So in this statement
int *p = new int[5];
There is allocated an array of 5 integer elements that are not initialized. Compare with definition
int a[5];
In this statement
int *p = new int(5);
there is allocated an object of type int that is initialized by 5. Compare it with the following definition
int x = int( 5 );
or simply
int x = 5;
I have a question:
Why does this throw an error (cannot convert from int* to int[5])
int static_Array[5];
int *dynamic_Array;
dynamic_Array = new int[5];
static_Array = dynamic_Array;
while this works fine?
int static_Array[5];
int *dynamic_Array;
dynamic_Array = new int[5];
dynamic_Array = static_Array; //This line changed
I am guessing that types int can be converted to int* by the compiler?
But then why couldn't int be converted to int* by the compiler as well?
Anyone can provide an actual explanation?
Thanks!
When a raw array is specified in a context where a pointer is expected, it converts to pointer to first item (in the sense of producing that pointer value), which is called a type decay.
Contexts where that doesn't happen include sizeof expression, typeid expression and binding to reference to array.
But essentially that means that raw arrays are not assignable, and of course you cannot assign a pointer to an array variable, for what should the result be.
However, if you put an array in a struct, then you can assign the struct. And that's what std::array is. But when you want an assignable dynamic size array, use std::vector.
In passing, there is is also a similar type decay for functions.
This one:
int static_Array[5];
int *dynamic_Array = new int[5]; // 1.
dynamic_Array = static_Array; // 2.
dynamically allocates an array and stores the address of first element in pointer dynamic_Array
overwrites this address with an address of the first element of the static_Array
But this one:
int static_Array[5];
int *dynamic_Array = new int[5];
static_Array = dynamic_Array;
attempts to initialize an array using an address (thus compiler gives error about invalid pointer to array conversion).
So why the first one works?
Because static array (on the right side) immediately decays to a pointer. This can not work the other way, there is no guarantee that this pointer points to an array.
int static_Array[5];
Here static_Array is const pointer to static_Array[0], you cannot modify it like,
static_Array = dynamic_Array;
int main()
{
int a = 10;
int *p; // int *p = a; gives me an error: invalid conversion from int to int *.
// Tell me why?
*p = a; // while this runs
cout << &a <<" "<<p;
}
Secondly &a and p gives 2 different values. According to me Address of a and the value stored in pointer p should be the same?
int *p = a, interpreted literally, takes the value stored in a and tries to interpret it as a memory address to store in p. While computationally legal, C++ won't allow this without an explicit typecast, because this is normally not what you want to do.
The reason why the statement int *p = a is different from *p = a is simple: the first statement, shorthand for the following
int *p;
p = a;
is initializing the pointer, so it expects a memory address on the RHS, while the second statement is assigning a value to the location pointed to by p, so expects (in this case) an integer on the RHS.
If you want to initialize p to point to a, you can use int * p = &a or p = &a instead, where & is the address-of operator. NEVER try to dereference uninitialized pointers! You will end up touching memory in an essentially arbitrary location, which could cause a segmentation fault (resulting in crash) or start overwriting other data in your program (resulting in obscure and non-reproducible bugs).
When you run your example code, p and &a have different values precisely because p was never assigned to point to the address of a. Some short background on why you might get any nonzero value in p at all: local variables are assigned from a special region of memory known as the stack, which also stores information about function calls and return addresses. Each process has their own stack. Crucially, though, unused regions of the stack aren't really zeroed out or otherwise cleaned up before use (except maybe in debug builds, which tend to assign really obvious values like 0xCCCCCCCC or 0xBAADF00D to uninitialized pointers). If your compiler doesn't automatically set default values for you (and release builds generally won't have such automatic initialization, for efficiency's sake), what you are seeing in p is what happened to be located in the memory assigned to p before your program set up its stack frame.
int *p = a; initializes a pointer p with a which isn't a pointer (hence the error), while *p=a; assigns a to the memory pointed to by p, syntactically speaking. Also, the former is an initialization, while the latter is assignment.
Note that in your case, *p=a invokes undefined behavior, as p doesn't point to program's legal memory, i.e you have not allocated memory for p.
You store a at the address that p points to (*p). If you want to store the address of a (&a) in p, you must use
p = &a;
Using int *p = a, gives an error, because p is a int*, while a is an int. Think of it as int* p = a.
int *p = a; - This means you are declaring a variable and assinging values to it. Variable name is p and its type is int * value you are assiging is a (10) which will be assigned to p. int *p = a; is equivalent to
int *p;
p = a;
We cant assing a int value to int *.
*p = a; - This you are assing int to the *p not p. so this is fine. Before doing this dont forget to allocate memory for p other it may leads to crash(undefined behaviour) because p might have some garbage values.
I hope you are trying to assing address of a to p. In that you case you can do like below.
int a;
int *p = &a;