2D smart pointers array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <memory>
using namespace std;

int main(){
	//this just builds a 2D array pi that looks like
	//0 1 2 3 4
	//5 6 7 8 9
	//10 11 12 13
	//...	   24
	int** pi=new int*[5];
	
	//this counter is augmented by 5 in every loop,
	//for the value to be 0...,5,..10etc
	int counter=0;
	for(int j=0;j<5;j++){	
		int* i=new int[5];
		for(int j=0;j<5;j++)
			i[j]=j+counter;
		counter=counter+5;

		pi[j]=i;
		//just to print out the array
		for(int k=0;k<5;k++)
			cout<<pi[j][k]<<" ";
		cout<<endl;
	}
	cout<<endl;

	//trying the same thing using smart pointers
	unique_ptr<int*[]> smp_pi(new int*[5]);
	counter=0;	
	for(int j=0;j<5;j++){
		unique_ptr<int[]> smp_i(new int[5]);		
		for(int k=0;k<5;k++){
			smp_i[k]=counter+k;		
			cout<<smp_i[k]<<" ";
		}
		counter=counter+5;
		cout<<endl;
		smp_pi[j]=&smp_i[0];
		//smp_pi[j]=smp_i; //this does not compile. why?
	}
	cout<<endl;

	for(int j=0;j<5;j++){	
		for(int k=0;k<5;k++)
			cout<<smp_pi[j][k]<<" ";
		cout<<endl;
	}

	return 0;
}


And the output:

0 1 2 3 4 
5 6 7 8 9 
10 11 12 13 14 
15 16 17 18 19 
20 21 22 23 24 

0 1 2 3 4 
5 6 7 8 9 
10 11 12 13 14 
15 16 17 18 19 
20 21 22 23 24 

0 21 22 23 24 
0 21 22 23 24 
0 21 22 23 24 
0 21 22 23 24 
0 21 22 23 24 

So I am trying to figure out how I could use smart pointers to produce the correct array 0...24. First thing that puzzles me is that, by looking at the third array of the output, it seems that all places of the smp_pi point to the same int array of size 5, instead of 5 different arrays of size 5. I was expecting to point to different arrays since a new smart pointer is declared in every loop (line 34). Second I was wondering about the syntax in line 42 that does not compile. So, if someone could enlighten me on how this could work correctly (for arbitrary size of arrays offcourse) but also what exactly I conceive erroneously here, it would be very helpful.Thank you!
There are several reasons why line 42 won't compile.
The most obvious one is that smp_pi[j] is a int* whereas smp_i is a unique_ptr<int[]>.
If you want to store smart pointers in your array, then your array has to be a smart pointers' array, not an int* array.
An other reason is that you're using unique_ptr. It's named unique_ptr for a reason. Read the doc !!

As for the 3rd array, it's because you declare your unique_ptr inside the 2nd loop.
A unique_ptr is supposed to free the memory of the managed pointer when its destructor is called. Since your smart pointer is declared inside a loop, each time the loop is exited the allocated memory is freed. So all the pointers you store with smp_pi[j]=&smp_i[0]; point to freed memory.
The reason all the line have the same value is just chance. Since you deallocate your array after each inner loop, there's a probability that at the next iteration's allocation your system allocator may choose the memory that was just freed. In that case the pointer returned by new will be the same as the one of the previous row.
It can be verified by checking if all smp_pi[j] contain the same address.
What a crazy idea, I have to try it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    // *** change 1 ***
    unique_ptr< unique_ptr<int[]> [] > smp_pi(
        new unique_ptr<int[]>[5]
    );

    counter=0;
    for(int j=0; j<5; j++){
        unique_ptr<int[]> smp_i(new int[5]);
        for(int k=0; k<5; k++){
            smp_i[k] = counter+k;
            cout << smp_i[k] << " ";
        }
        counter=counter+5;
        cout<<endl;
        smp_pi[j] = move(smp_i);  // **** change 2
    }
    cout<<endl;

    for(int j=0;j<5;j++){
        for(int k=0;k<5;k++)
            cout<<smp_pi[j][k]<<" ";
        cout<<endl;
    }


(crazy because there are so many more convenient 2D container libraries)

PS: don't forget to delete[] your first arrays.
Last edited on
Topic archived. No new replies allowed.