Pointer problems

I am confused with pointers and have a few questions regarding the following code :

1
2
3
4
5
6
7
  int x;
  cin>>x;
 int* pointer2 = new int[x];
    delete [] pointer2;
      
    int* pointer21[x];


1) Are pointer 2 and pointer 21 the same thing?

1
2
3
4
5
6
7
8

     int* pointer32[x][x];
    int* pointer33[x][x][x];
    int* pointer34[x][20][30];
    int* pointer35[20][x][x];
    int* pointer39[x][20];
    int* pointer391[x][20];


2) how do you define the above pointers?
3) is the procedure to delete these same as pointer2 in the above code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

    int* pointer36 = new int[x];
    for(int i = 0;i<x;i++){
        pointer36[i] = *new int;
        
    }
    int* pointer37 = new int[x];
    for(int i = 0;i<x;i++){
        pointer37[i] = *new int[x];
        
    }
    int* pointer371 = new int[x];
    for(int i = 0;i<x;i++){
        pointer371[i] = **new int*[x];
        
    }


4)how do you define the above 3 statements that are inside the for loop ?

1
2
3
4
5

    int** pointer42 = new int[x][5];
    // the above statement gives an error :
    // cannot initialize a variable of type 'int**' with a rvalue of type 'int(*)[5]'


5) Can somebody explain the above error ?

Thanks !!
1) No. They are two separate variables that point to different types of data.
2) A mess. A nonstandard mess (yet). I suppose you could also call them multidimensional arrays of pointer-to-int. If you mean define as in create, they are already defined.
3) AFAIK no. Traditionally you have quite a bit of loops to write to delete stuff pointed by each dimension of the arrays. That being said, I never used "runtime-sized arrays with automatic storage duration", so I'm not really sure how they clean up after themselves in this scenario.
4) A mess. A memory leak mess, plus a segmentation fault mess in the third case (and if you try to delete array elements).
5) I'm not sure about that.
Last edited on
what do the following statements in the above code actually mean ?

1
2
3
4
5

pointer36[i] = *new int;
pointer37[i] = *new int[x];
 pointer371[i] = **new int*[x];
vxk wrote:
pointer36[i] = *new int;
new int — Create new int somwhere in memory; returns ponter to newly created integer.

*new int; — Dereference returned pointer; returns actual value, produces undefined behavior as variable is uninitialized

pointer36[i] = *new int; — Assigns said value to array element with index i 

This code leaks, as allocated memory never deleted and pointer to it is lost.

vxk wrote:
pointer37[i] = *new int[x];
new int[x]; — Creates new array of x ints somwhere in memory; returns ponter to first array element created integer. Assumes that x is compile-time constant. If it is a variable, this code is not valid. Your compiler might have extension to allow it. If it is the case, turn it off immediatly.

*new int[x]; — Dereferences returned pointer; returns value of first array element, produces undefined behavior as variable is uninitialized.

pointer37[i] = *new int[x]; — Assigns said value to array element with index i 

This code leaks, as allocated memory never deleted and pointer to it is lost.

vxk wrote:
pointer371[i] = **new int*[x];
new int*[x]; — Creates new array of x pointers to int somwhere in memory; returns ponter to first array element created integer. Assumes that x is compile-time constant. If it is a variable, this code is not valid. Your compiler might have extension to allow it. If it is the case, turn it off immediatly.

*new int*[x]; — Dereferences returned pointer; returns value of first array element, produces undefined behavior as variable is uninitialized.

**new int*[x]; — Dereferences value returned by previous operation. As we allocated array of pointers it would be a pointer to int, dereferenced it would be just value of stored int. This code produces an undefined behavior and is likely to crash program as you are trying to dereference uninitialized pointer.

pointer371[i] = **new int*[x]; — Assigns said value to array element with index i 

This code leaks, as allocated memory never deleted and pointer to it is lost.


All that code is extremely bad and dangerous. It should not be written even for academic purposes.
Last edited on
1) new int Allocate memory for an int, return a pointer to the start of the chunk of memory.
*new int Dereference that pointer to read the value it points to.
pointer36[i] = Copy that value into an element of the array.

2) new int[x] Allocate memory for an array of ints with x elements, return a pointer to the first element in the sequence.
*new int[x] Dereference that pointer to read the value it points to (ignoring all other elements).
Then copy value.

3) new int*[x] Allocate memory for an array of pointer-to-int with x pointers (elements), return a pointer to the first element in the sequence (so return a pointer to a pointer: int**).
*new int*[x] Dereference that pointer to read the value it points to (ignoring all other elements).
**new int*[x] Since the dereferenced value is a pointer you can dereference it again to read the value in points to.
Then copy value.


Note that you never store a reference to the memory you allocate, you only store (some of the) values it contains. Without a reference (pointer) to the chunks of memory you can't delete it.
This is called memory leak: allocating memory and losing all references to it so that it can't be deallocated anymore.

Also, the values contained in the memory you allocate will be garbage because the data is not initialized.
In the third case this most likely results in a segmentation fault, an error that occurs whenever you try to access invalid memory (i.e. memory not allocated by your program or special reserved locations).
Because the content of the array is not initialized the first dereference yields a pointer with a garbage value. Dereferencing that will most likely try to read memory you don't own and cause a segmentation fault.
> Are pointer 2 and pointer 21 the same thing?

EDIT: corrected by maeriden

They are of the same type 'pointer to int'. No.
Assuming that x was non-negative:
pointer2 was valid when it was intialised; but it is invalidated after delete [] pointer2; pointer 21 may or may not hold the same address that pointer2 held earlier.


> how do you define the above pointers?

Assuming that 'x' was a strictly positive integral-constant-expression, the above are not pointers; they are arrays. For instance, pointer32 is an 'array of x array of x pointer to int'



1
2
> int** pointer42 = new int[x][5];
> // the above statement gives an error  

> Can somebody explain the above error ?

1
2
3
4
using array_type = int[5] ; // array of 5 int
array_type* pointer42 = new array_type[x] ;
// or: int (*pointer42)[5] = new int [x] [5] ;
// or, simply: auto pointer42 = new int [x] [5] ; 


The moral of the story is short and sweet: use std::vector<>
Last edited on
They are of the same type 'pointer to int'.

Shouldn't pointer21 be int*[]?
Are variable size arrays even legal in C++? Did that get added in C++14?
> Shouldn't pointer21 be int*[]?

Yes. My mistake; misread it. Thanks!
Are variable size arrays even legal in C++? Did that get added in C++14?
They should be added in the stadard with C++14, but according to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html most compilers already support it as an extension.
Sorry for being a complete newbie but just for conforming how do you read:


int* pointer21[x];

is it a one dimensional array of pointers?
or a pointer pointing to the 1st element of array of size x?

and what is int*[]? from the line Shouldn't pointer21 be int*[]?

Thanks!!
int* pointer21[x];

is it a one dimensional array of pointers?
or a pointer pointing to the 1st element of array of size x?
It is one dimensional aray of pointers.
As all arrays it can be threated (and in several specific cases decays to without warning) as pointer to it first element: pointer to pointer to int. Some specific array operations are also avaliable for pointers, so some confusion between two exist.

and what is int*[]?
Arrays have a distinct type from pointers; for compile time arrays it allows some operations like sizeof() be applied differently, enables some template tricks and allows some assumptions about multidimensional arrays work. You will only see things like int[5] in compiler errors.
In your case it would mean array of runtime size containing pointers to int.
@MiiNiPaa
for compile time arrays it allows some operations like sizeof() be applied differently, enables some template tricks and allows some assumptions about multidimensional arrays work


i think i don't understand this(because there is no example) and do I need to right now ? because i am not doing any heavy template programming .. :P


pointer371[i] = **new int*[x];
new int*[x]; — Creates new array of x pointers to int somwhere in memory; returns ponter to first array element created integer. Assumes that x is compile-time constant. If it is a variable, this code is not valid. Your compiler might have extension to allow it. If it is the case, turn it off immediatly.


I am using the default Xcode 5.1 settings and don't have any extensions enabled
Here is a pic :

http://imgur.com/FMMOdxq

or i missed something ?

Thanks!
Last edited on
I am using the default Xcode 5.1 settings and don't have any extensions enabled
Xcode is and IDE, not compiler. I believe, it uses Clang as compiler. It has VLA support enabled by default if you are using C++11 mode, but you actually might use C++14 mode where VLA are included in standard. So I might be too quick to judge here.

i think i don't understand this(because there is no example) and do I need to right now ? because i am not doing any heavy template programming .. :P
One thing you need to know as it is a common pitfall:
1
2
3
4
5
6
7
8
9
10
11
int  x[10];
int* y = new int[10];
//Common idiome to find amount of elements in array
//Works because compiler knows that x has type of int[10]
//And able to correctly deduct its size
std::cout << (sizeof(x) / sizeof(x[0]));

//Will always output either 1 (for 32bit pointer and 32bit int)
//or 2 (for 64bit pointer and 32bit int)
//Because type of y is just int*
std::cout << (sizeof(y) / sizeof(y[0]));

One last question to boost my confidence(really low) :

1
2
3
4
5
6

int main(){
int x;
cin>>x;
int* pointerx[x][x]; 


1)The above code is a 2d array where each element is a pointer
2)Since the pointers I defined above are not on the free store (not allocated using "new"), I cannot delete them.
3)x can be a const int type or a value taken in during run time through cin.

4)The existence of the above code to be correct is because its is non-standard compiler extension?(some one just argued with me this)


Are all the statements true ..?
1) yes.
2) Those pointer are uninitialized and only safe operation with them is to point them to the valid object (as those returned by new) and therefore dangerous to use (because you cannot test if they are pointing to the valid object). It is a good idea to explicitely set new pointers to nullptr so in case of accidental use you will know immediatly.
3) In standard C++ before C++14 x can only be compile tyme constand. In C++14 Variable Length Arrays were added which made this construction legal.
4) If your compiler set to use C++11 standard then it is unstandard extension and should be avoid. If it uses C++14 standard, then it is standard.

I do not like VLA, so I am a little pejust here.
> In C++14 Variable Length Arrays were added which made this construction legal.

ARBs (arrays of runtime bound) is the term normally used in C++.
(functionally similar to, but conceptually different from C99's VLAs).

ARBs (and std::dynarray) didn't make it to C++14; instead they were pushed out into an 'Array Extensions TS'

This TS was expected to be released in early 2015, but AFAIK, it won't be out any time soon. There is consensus in the EWG that a standard library wrapper for ARBs is essential; the TS is currently in suspended animation because there is no consensus on what that wrapper should precisely be. The EWG will have to look at revised/fresh proposals in November. Repeat: AFAIK.
Sorry guys for all the fuss and thank you for patiently answering my question,
I had to share this :

int* pointer1[x][x]; is not legal in C++14. It was added to early drafts but then removed well before the final specification.

I am using c++11 in Xcode 5.1 and and i don't know how to remove the compiler extension(and don't know why even they included it of its not a standard in the first place)

Thanks!
I am not familiar with Xcode, but there should be something to control compiler settings. There should be option to stictly adhere to standard (or at least to issue warnings).

It is -pedantic (warnings) or -pedantic-errors (errors) compiler flags if it will be any help for you
Topic archived. No new replies allowed.