Copying arrays using pointers?

Hi guys, so basically this is what I tried to do:
I initialized an array on the heap, then made a pointer (p1) pointing to it, then output all the values of the array that p1 pointed to. (that part works fine)
Then I made a new array (second) the same size as the first, then initialized a pointer that pointed to it, then tried to copy them by iterating through all the values of the first pointer, but unfortunately it just spits out 0's for the second array instead of the first array. Why is this, and how should I be copying these arrays with pointers? (I'm obviously doing it wrong)

If I have used incorrect terminology or syntax then tell me, I'm struggling when it comes to conceptualizing pointers and references.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

int main() {
	int* first = new int[10];
	int n[10]={1,2,4,8,16,32,64,128,256,512};
	first = n;
	int* p1 = first;
	for(int i=0; i<10; ++i) {
		cout << *p1 << endl;
		++p1;
	}
	int* second = new int[10];
	int* p2 = second;
	for(int i=0; i<10; ++i) {
		p2 = p1;
		++p1;
		++p2;
		cout << second[i] << "  ";
	}
	cout << endl;
}
You forgot to have p1 point back to the beginning. In something like this, I wouldn't be modifying the pointer. You can treat the pointer like an array: p1[I].

Random Note:
You forgot to call delete to free resources.

Edit:
You also have not copied anything. Your for loop continuously updates p2 and p1 until they are both way out of bounds, but the array at second is left untouched.
Last edited on
Alright so I think I understood what you meant, but I'm having segmentation faults with my output inside the for loop and it's 0s when I move it outside.

1
2
3
4
5
6
7
8
9
	int* second = new int[10];
	int* p2;
	for(int i=0; i<10; ++i) {
		p2[i] = p1[i];
	}
	second = p2;
	for(int i=0; i<10; ++i) cout << second[i] << "  ";
	cout << endl;
}


And as to the delete, I'm unclear whether I should delete the pointersdelete p1 or if I should delete the arrays. delete[] first

I'm sure this is much easier than I'm making it.

EDIT: Delete gives me a massive runtime error which is why I chose not to use it until I got the rest figured out. Here it is though:
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
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00007f27a16005c0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76518)[0x7f27a0b76518]
/lib64/libc.so.6(cfree+0x6c)[0x7f27a0b7b4bc]
./a.out[0x400c31]
/lib64/libc.so.6(__libc_start_main+0xe6)[0x7f27a0b1ec16]
./a.out[0x4009f9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:1b 58967086                           /home/ugrads/s/shilaly/113/Lab4/second/a.out
00601000-00602000 r--p 00001000 00:1b 58967086                           /home/ugrads/s/shilaly/113/Lab4/second/a.out
00602000-00603000 rw-p 00002000 00:1b 58967086                           /home/ugrads/s/shilaly/113/Lab4/second/a.out
00603000-00624000 rw-p 00000000 00:00 0                                  [heap]
7f279c000000-7f279c021000 rw-p 00000000 00:00 0
7f279c021000-7f27a0000000
7f27a0b00000-7f27a0c6d000 r-xp 00000000 08:02 2211848                    /lib64/libc-2.11.3.so
7f27a0c6d000-7f27a0e6d000 ---p 0016d000 08:02 2211848                    /lib64/libc-2.11.3.so
7f27a0e6d000-7f27a0e71000 r--p 0016d000 08:02 2211848                    /lib64/libc-2.11.3.so
7f27a0e71000-7f27a0e72000 rw-p 00171000 08:02 2211848                    /lib64/libc-2.11.3.so
7f27a0e72000-7f27a0e77000 rw-p 00000000 00:00 0
7f27a0e78000-7f27a0e8d000 r-xp 00000000 08:02 2211866                    /lib64/libgcc_s.so.1
7f27a0e8d000-7f27a108c000 ---p 00015000 08:02 2211866                    /lib64/libgcc_s.so.1
7f27a108c000-7f27a108d000 r--p 00014000 08:02 2211866                    /lib64/libgcc_s.so.1
7f27a108d000-7f27a108e000 rw-p 00015000 08:02 2211866                    /lib64/libgcc_s.so.1
7f27a1090000-7f27a10eb000 r-xp 00000000 08:02 2211856                    /lib64/libm-2.11.3.so
7f27a10eb000-7f27a12ea000 ---p 0005b000 08:02 2211856                    /lib64/libm-2.11.3.so
7f27a12ea000-7f27a12eb000 r--p 0005a000 08:02 2211856                    /lib64/libm-2.11.3.so
7f27a12eb000-7f27a1309000 rw-p 0005b000 08:02 2211856                    /lib64/libm-2.11.3.so
7f27a1310000-7f27a13f8000 r-xp 00000000 08:02 48187287                   /usr/lib64/libstdc++.so.6.0.17
7f27a13f8000-7f27a15f7000 ---p 000e8000 08:02 48187287                   /usr/lib64/libstdc++.so.6.0.17
7f27a15f7000-7f27a15ff000 r--p 000e7000 08:02 48187287                   /usr/lib64/libstdc++.so.6.0.17
7f27a15ff000-7f27a1601000 rw-p 000ef000 08:02 48187287                   /usr/lib64/libstdc++.so.6.0.17
7f27a1601000-7f27a1616000 rw-p 00000000 00:00 0
7f27a1618000-7f27a1637000 r-xp 00000000 08:02 2212125                    /lib64/ld-2.11.3.so
7f27a17f3000-7f27a17f8000 rw-p 00000000 00:00 0
7f27a1834000-7f27a1836000 rw-p 00000000 00:00 0
7f27a1836000-7f27a1837000 r--p 0001e000 08:02 2212125                    /lib64/ld-2.11.3.so
7f27a1837000-7f27a1838000 rw-p 0001f000 08:02 2212125                    /lib64/ld-2.11.3.so
7f27a1838000-7f27a1839000 rw-p 00000000 00:00 0
7fff51ede000-7fff51eff000 rw-p 00000000 00:00 0                          [stack]
7fff51f98000-7fff51f99000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
4197661  0  -1587542592  32551  6303808  0  1374671248  32767  4196816  0  Aborted
shilaly@linux2:~/113/Lab4/second>
Last edited on
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
#include <iostream>
using namespace std;

int main() {
	int* first = new int[10];
	int n[10]={1,2,4,8,16,32,64,128,256,512};
	first = n;  //Memory leak. No pointer points to the array you allocated with "new int[10]"
	int* p1 = first;
	for(int i=0; i<10; ++i) {
                   //You can replace the two lines below with a simple p[I]
		cout << *p1 << endl;
		++p1;
	}
//By this point, p1 still points to the last element in the array n
	int* second = new int[10];
	int* p2; //Forgot to initialize this pointer; current points to random lcoation
	for(int i=0; i<10; ++i) {
		p2[i] = p1[i]; //Segfault. Who knows where p2 is pointing to
	}
	second = p2; //This line should not exist. Causes second memory leak
	for(int i=0; i<10; ++i) cout << second[i] << "  ";
	cout << endl;
//No freeing of resources
}


Imagine your pointers like this:

Memory Space

Stack (Where program is located):
   n -> {1,2,4,8,16,32,64,128,256,512}

Heap (Random memory you can allocate):
   first -> int[10]
   second -> int[10]

After your program runs (and crashes):

Stack (Where program is located):
   first -> n -> {1,2,4,8,16,32,64,128,256,512} <- p1 (last value)

Heap (Random memory you can allocate):
    int[10]
    int[10]
(Orphaned memory)

Some Other Memory:
   second -> p2 -> ???


How to copy one array to another with the same size:
1
2
3
int arr1[3] = {1, 2, 3}, arr2[3];
for(int I(0); I < 3; ++I)
   arr2[I] = arr1[I];


In fact, you don't really need p1 nor p2 in your program.

In your case, call delete[].
1
2
3
delete[] first;
delete[] second;
//Make sure they still point to their respective arrays 
Last edited on
Thanks for your help, I got it to work, but I had to change my first array to be allocated on the stack, because I couldn't find a way to assign the values using new int[10]{...}.

I think the problem was me incrementing the pointer in the first for loop, and it caused it to go out of bounds in the second. (Maybe)

Also, I wouldn't use p1 or p2 either, but sadly it's required to use pointers to change the values in this program.

Anyway here's my final code, for anyone else's benefit. I commented out delete[] first because I changed that in the beginning and it's not on the free store.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main() {
	int first[]={1,2,4,8,16,32,64,128,256,512};
	int* p1 = first;
	for(int i=0; i<10; ++i) {
		cout << p1[i] << endl;
	}
	int* second = new int[10];
	int* p2 = second;
	for(int i=0; i<10; ++i) {
		p2[i] = p1[i];
	}
	for(int i=0; i<10; ++i) cout << second[i] << endl;
	//delete[] first;
	delete[] second;
	cout << endl;
}

Last edited on
...it's required to use pointers...

The name of an array decays into a pointer. You can write either first[I] or *(first + I) if you wanted.
And second is already a pointer.
Oh I must have massively misunderstood then, so basically this whole time I've had pointers pointing to pointers?
No wonder you thought I was silly.. That clears a few things up..
Thanks again!
No wonder you thought I was silly..

Nonsense. I just gave you some FYIs.

...I've had pointers pointing to pointers?

Here's another one.
Pointers hold a memory address, so when you write p1 = first, the memory address first holds is copied to p1. So they point to the same location, but not to each other.

A pointer to pointer looks something like:
1
2
3
Type a;
Type* ptr(&a);
Type** ptr_to_ptr(&ptr);
Ahh ok that makes more sense then. So, say I wanted to get rid of p1 altogether, but still have first retain it's values? Why does something like
1
2
 int*first = new int[10];
first[10]={1,2,4,8,16,32,64,128,256,512};

not work?
 error: cannot convert â<brace-enclosed initializer list>â to âintâ in assignment

Sorry if it's too many questions, I'm trying to get a grip on why certain syntax throws errors.
Think about regular arrays.
1
2
int arr[3];
arr[3] = {1, 2, 3};

There are two problems with this:
1) After declaration, arr[I] will be accessing the array at that index. So arr[3] is out of bounds.
2) The second line attempts to assign an entire list to an int, so it is like writing int I = {1, 2, 3};.

When you allocate memory for an array, you cannot pass any initial values. Everything becomes the type's default value.

Unfortunately, this means you'd have to use a for loop to assign initial values.
you'd have to use a for loop to assign initial values. 

That's what I was afraid of.. Thank you for all your help though!
Topic archived. No new replies allowed.