Confused: Pointers to Dynamic Arrays Syntax - c++

int* p_bob = new int;
*p_bob = 78;
The above code makes sense to me. I use the de-reference operation to allocation new memory and assign a value of 78.
int* p_dynint = new int[10];
*p_dynint[2] = 12;
This however doesn't make sense. If I try to use the de-reference operator on p_dynint[] I get an error. Why would an array be any different?

*p_bob = 78; this assigns the value 78 to the memory pointed to by p_bob (which represents an int).
p_dynint[2] = 12; simply accesses the 3rd element.
p_dynint[2] is actually equivalent to *(p_dynint+2).

p_dynint[2] is equivalent to *(p_dynint + 2). The derefencing is implied in the [] operator.

It is no real problem to do this:
int* p_dynint=new int[10];
//write first element
*p_dynint=10;
//write second element
*(p_dynint+1)=20;
//write three elements to std::cout
std::cout<<p_dynint[0]<<p_dynint[1]<<p_dynint[10]<<std::endl;
This example also highlights a problem with arrays. You can read and write anything. The output generated by p_dynint[10] is an int but its value is just the next few bytes converted to an int.
Use containers if possible (for further reasoning read this)

Related

CPP , creating array and i see only one parameter

i create an Array with 3 numbers;
i see only one number instead 3
int *ArrayA;
ArrayA = new int[3];
ArrayA[0] = 2;
ArrayA[1] = 4;
ArrayA[2] = 6;
when i debugging and follows ArrayA i see only 2;
what could be the problem?
Your object ArrayA is of type int *. Hence it points to a single int. The fact that you have it point at an int[3] array doesn't change that fact. Your debugger can also not guess that you want it to display more than one value.
Instead of using raw c-style arrays, it is usually recommended to use an std::array.
std::array<int,3> arrayA = {2,4,6};
This is not a problem. It's as expected because ArrayA is a pointer. So pointer base address and the address of the 1st element of the array are same. Hence you always see 2 in your debugger. Not sure which debugger you are using, you can try to add ArrayA[index] or *(ArrayA + index) then you can see other values as well.

Malloc of pointer to an array- C++

I have a function which gets as a parameter a pointer to array,
e.g. int** segs.
I need to allocate (in the function-body) memory for the array, which has size 100 for example.
My attempt was:
*segs=(int*)(malloc(100));
So far so good.
I put a value into *segs[0], and still everything is great.
But... when I try to reach *segs[1], I get an "invalid write of size 4" error from valgrind, which leads to seg-fault.
I have no idea why does that happen.
I tried to reach to *segs[2], but then I get even something weirder-
Error of uninitialised value of size 8.
Due to operator precedence, *segs[N] is treated as *(segs[N]), which is ok when N is equal to 0. However, when you do the same thing using the index 1, things break since nothing has been allocated for segs[1]
For any index other than zero, you need to use (*segs)[N].
It will be easier to use a temporary pointer in the function.
int* ptr = (int*)(malloc(100));
*segs = ptr;
// and then
ptr[0] = ...; // Good
ptr[1] = ...; // Good
...
ptr[99] = ...; // Still good
Upgrading to C++ Way
Pass the pointer by reference.
void foo(int*& segs) { ... }
Use new instead of malloc to allocate memory.
segs = new int[100];
Better yet, use std::vector insteady raw arrays.
void foo(std::vector<int>& segs) { ... }

Understand how this double becomes an array?

So I'm currently reading and learning a code from the internet (related to artificial neural network) and I found a part of the code that I don't understand why it works.
double* inputNeurons;
double* hiddenNeurons;
double* outputNeurons;
This is how it was declared. Then in this next code, it was changed and used as an array?
inputNeurons = new( double[in + 1] );
for ( int i=0; i < in; i++ ) inputNeurons[i] = 0;
inputNeurons[in] = -1; // 'in' is declared in the function as an int
So, I want to understand why and how it works. Did it become an array of "doubles"? If so, in what way can I also use this? Can this be used for struct or even class?
Every array can be treated as a pointer. But that does not mean every pointer is an array. Do not mix this up!
Assuming we have an array int test[..], the variable name also represents the address where the array is stored in the memory. So you could write
int * p = test;
At that moment my pointer p "becomes" an array, where "becomes" means 'points to an array'. Your example is similar - the only difference is that the memory is allocated dynamically (heap) and not on the stack (as in my example).
So how are the elements accessed?
Let's say, we want to get the first element (index 0).
We could say
int i = test[0];
or we could say
int i = *p;
Now we want to get the element at index 1:
int i = test[1];
Or - by using pointer arithmetics we could write
int i = *(p + 1);
In C++ (and C) pointers support indexing operator [] which basically adjusts the value of the pointer by the amount specified times the size of the type pointed.
So basically
inputNeurons[5] = 0;
is equivalent to
*(inputNeurons+5) = 0
Now this doesn't give you any guarantee about the fact that inputNeurons points to an address which is correctly allocated to store at least 6 double values but syntactically it is correct and well defined.
You are just adjusting an address to point to the i-th element of a given type starting from the specified address.
This means that
double x;
double* px = &x;
px[5] = 0;
Is syntactically correct although it is wrong, since px+5 is an address which points to memory which has not been reserved correctly to hold that value.
The pointer of type double (double* inputNeurons;) just gets assigned to point to the beginning of an dynamically allocated array (new( double[in + 1])) of the same type. It does not become an array.
You can do this with any other pointer and regular array of the same type. As a matter of fact an array is a pointer to specific address (to its beginning, i.e. to the element with index: 0).
When you increment the pointer by + 1, that one means 1 * type_size (i.e 1 * size_of_double)
In your case: inputNeurons points to the address of the first element of the array. If you dereference it: *inputNeurons, you will get the value stored at that address (if inputNeurons was an array, it would be equivalent to: inputNeurons[0] ). To access the next element just increment by one (*inputNeurons + 1).

Behavior in case of pointer increment. C++

Consider the following code:
int main()
{
int* p = new int(3);
p+=4;
std::cout<<*p<<std::endl;
}
My compiler (Visual Studio 2012) prints: -7514522142 int this case.
So can we somehow deduce the output and is this code legal?
You are accessing memory (allocated for a single int object) out of bounds. The behaviour is undefined, i.e. not deducible. The program should not be considered legal, despite being syntactically valid.
So can we somehow deduce the output and is this code legal?
Pointers are incremented in multiples of the size of the type they point to. When you add 4 to p, you're adding 4 * sizeof(int), not just 4 bytes.
If you're trying to make p point to the "next" integer, increment it by 1, not 4. Otherwise, p will point to memory beyond the end of what you allocated.
In fact, if I'm not mistaken your allocation only creates a single int with the value 3, not three separate ints:
int* p = new int(3);
Try commenting out the p += 4; line and you should get '3' as the output. Considering that, juanchopanza's answer above is spot on.

C++ what exactly does new <datatype>(<value>) do?

In this code:
int * p = new int(44);
p is allocated on the heap and the value it points to is 44;
but now I can also do something like this:
p[1] = 33;
without getting an error. I always thought
int * p = new int(44);
was just another way of saying "P is allocated on the heap and points to an address containing 44" but apparently it makes p a pointer to an array of ints? is the size of this new array 44? Or is this result unusual.
You were right: P is allocated on the heap and points to an address containing 44. There's no array allocated. p[1] = 33; is what they call "undefined behavior". Your program might crash, but it's not guaranteed to crash every single time you do this.
int *p_scalar = new int(5); //allocates an integer, set to 5.
If you access p_scalar[n] (n <> 0) it may crash
In your example, the C++ language gives you a default implementation for the subscript operator for pointers that looks somehow similar to this:
(*Ptr)& operator[](size_t index)
{
return *(address + index*sizeof(*Ptr));
}
This can always be overloaded and replaced for any type. Integers are not an exception, when you say:
int * pointer = alocate_int_array();
pointer[1] = 1;
You're using the compiler-augmented default implementation of that operator.