Writing to a Pointer Array

I haven't played with pointers much, especially not with arrays so I'm at a loss here. I've been looking in my book and all over the web but I can't find an answer. My problem says this:

"You have the following code segment in the main():
int *numArray = NULL;
ProcessArray(numArray, 5);
After the ProcessArray function is called, the numArray must contain 5 array elements entered by the user."


So my question is how do I write user input values to the pointer? Because my current set up causes lots of crashes.

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
#include <iostream>
using namespace std;

int ProcessArray(int array[], int num)
{
	for(int i = 0; i < num; i++)
	{
		cout << "Input value for placement " << i+1 << ": ";
		cin >> array[i];
	}
	return 0;
}

void PrintArray(int array[], int num)
{
	cout << endl;
	for (int i = 0; i < num; i++)
	{
		cout << array[i] << endl;
	}
	cout << endl;
}

int main()
{
	int *numArray = NULL;

	ProcessArray(numArray, 5);
	PrintArray(numArray, 5);

	system("pause");
	return 0;
}
Last edited on
Your book is.... well.... This is a confusing assignment. The only way to make this work is to pass the pointer to the array by reference. This is kind of clunky. A more reasonable way would have been to just return the pointer (although passing ownership like this in any form is generally a bad idea... so the whole concept of this assignment is kind of bad)

Anyway.. ranting over. Here's a simplified example of the difference between passing by value and passing by reference:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void byval(int v)  // creates a COPY of the passed in variable
{
    v = 5;  // modifying v here will NOT modify the original variable, because 'v' is its own copy
}

void byref(int& r)  // creates a REFERENCE to the passed in variable
{
    v = 5;  // changing v here WILL modify the original variable, because 'v' is referring to it
}

int main()
{
    int foo = 0;
    byval(foo);
    cout << foo; // prints "0" as you'd expect
    byref(foo);
    cout << foo; // prints "5" as you might expect
}


So... to pass a value in to a function and expect that function to change that value... you have to pass it by reference.

Why this is weird in your case is because it's expecting you to pass a pointer by reference. Now... pointers are a little tricky, but they work the same way:

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

void byval(int* p) // p is a copy of the passed in pointer
{
    p = &five; // make p point to five.  But will not change what the original pointer pointed to
}

void byref(int*& rp)  // rp is a reference to the pointer
{
    rp = &five; // this WILL modify the original pointer
}

int main()
{
    int* ptr = &zero;
    cout << *ptr;  // prints "0"

    byval(ptr);
    cout << *ptr;  // prints "0"  (ptr has not changed)

    byref(ptr);
    cout << *ptr;  // prints "5" (ptr has changed to point to something else
}


See? Exactly the same.


Why this is tricky is because while you can't modify the pointer when it's passed by value... you can modify whatever the pointer points to. So in a way... passing a value through a pointer is similar to passing it by reference.

But I'll spare an example here since it's unrelated to your problem at hand.
Well now I can input values although I'm not sure if it's storing them correctly.

This is the output I get:
Input value for placement 1: 5
Input value for placement 2: 7
Input value for placement 3: 3
Input value for placement 4: 4
Input value for placement 5: 6

001AF83C
001AF840
001AF844
001AF848
001AF84C

Press any key to continue . . .


But I'm not sure if I set up the printing terms correctly or not so I can't tell if my input isn't being accepted properly or if I just messed up the print function.

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
#include <iostream>
using namespace std;

void ProcessArray(int*& pointer, int num)
{
	for(int i = 0; i < num; i++)
	{
		int val;
		cout << "Input value for placement " << i+1 << ": ";
		cin >> val;
		pointer = &val;
		*pointer++;
	}
}

void PrintArray(int*& pointer, int num)
{
	cout << endl;
	for (int i = 0; i < num; i++)
	{
		cout << pointer << endl;
		pointer++;
	}
	cout << endl;
}

int main()
{
	int *numArray = NULL;

	ProcessArray(numArray, 5);
	PrintArray(numArray, 5);

	system("pause");
	return 0;
}
A pointer has to point to something. You are making your pointer point to the local 'val' variable. The problem is that 'val' is destroyed at the end of the loop. So after that loop, your pointer is pointing to a variable that no longer exists. IE: it's a bad pointer.

The goal of this assignment is to allocate memory dynamically. Like with the new[] keyword.
Okay so I tried using the new statement. I'm not sure that I'm using it right. But I also put a cout statement right after the cin statement and it doesn't appear to be taking the variables correctly at all.

Input value for placement 1: 4
003B50A8
Input value for placement 2: 3
003B5228
Input value for placement 3: 6
003B53A8
Input value for placement 4: 7
003B5528
Input value for placement 5: 4
003B56A8
Press any key to continue . . .


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
#include <iostream>
using namespace std;

void ProcessArray(int*& pointer, int num)
{
	for(int i = 0; i < num; i++)
	{
		int val;
		cout << "Input value for placement " << i+1 << ": ";
		cin >> val;
		pointer = &val;
		pointer = new int;
		cout << pointer << endl;
		*pointer++;
	}
}

int main()
{
	int *numArray = NULL;

	ProcessArray(numArray, 5);

	system("pause");
	return 0;
}


Also thank you for taking the time to help me with this.
Played around with it more while I waited for a reply and got it to work. Thank you so much for the help :)

Final Code:
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
#include <iostream>
using namespace std;

void ProcessArray(int*& pointer, int num)
{
	for(int i = 0; i < num; i++)
	{
		int val;
		cout << "Input value for placement " << i+1 << ": ";
		cin >> val;
		int *p = new int;
		p = &val;
		pointer = p;
		cout << *pointer << endl;
		pointer++;
	}
}

int main()
{
	int *numArray = NULL;

	ProcessArray(numArray, 5);

	system("pause");
	return 0;
}
It's still not quite right. Try passing your array to your original PrintArray function (which is right) to see that it isn't working.

Let's take a step back and understand what each line of code does. This is the "rubber duck" debug method:

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
void ProcessArray(int*& pointer, int num)
{
    // This is a loop that loops 'num' times.  Each time it loops, 'i' is incremented.
    //  Note that this means everything in this body is going to be repeated 'num' times
    for(int i = 0; i < num; i++)
    {
        // Create a temporary variable named 'val'
        int val;
        
        // Output some text for the user
        cout << "Input value for placement " << i+1 << ": ";
        
        // Get the user input... put it in our temporary 'val' variable
        cin >> val;
        
        // Create a new, unnamed int (let's call it 'foo') with the 'new' keyword.
        //  Assign a pointer to foo to our 'p' pointer.  Now, 'p' points to our newly created 'foo'
        int *p = new int;
        
        // Now... this is where it gets messed up.  Even though we just assigned p to point to foo,
        //  we are THROWING THAT AWAY and telling p to point to 'val' instead.  'foo' gets lost
        //  because nothing points to it anymore.  IE:  it becomes a memory leak.
        p = &val;
        
        // We assign our passed in 'pointer' to point to whatever 'p' points to.  Since p points
        // to 'val'... this means that 'pointer' will also point to 'val'
        pointer = p;
        
        // This will print the contents of whatever 'pointer' points to.  Since it points to 'val'
        //  this will print the contents of 'val'
        cout << *pointer << endl;
        
        // This increments 'pointer' to point to whatever memory is 1 space after 'val'.  IE:
        //  it makes it point to random garbage that is not assigned to anything.  DANGEROUS
        pointer++;
    }
}


You have the exact same problem you had before: 'pointer' is not pointing to an array. It's pointing to some random garbage area in memory. What's worse... you allocated a bunch of individual integers that you never used, and are now memory leaks because nothing points to them so it is impossible to unallocate them.




You should go back and reread the section in your book on the 'new' keyword. Specifically... how to use new[] to allocate arrays. You are not allocating arrays here, you are allocating individual variables.

Example:

1
2
int* example = new int[10];  // <- we allocate an array of 10 ints.
                             // 'example' points to the first element in that array 
Last edited on
Topic archived. No new replies allowed.