Pointers and Dynamic memory

This is a question about a homework problem and before anyone gets all mad, I am not asking for anyone to do this problem. I just have some questions about it as I don't really understand pointers.

Here is the problem:

Write a program that has four functions—main, create_array, populate_array, and find_val. The main function should create an int pointer and pass it to the create_array function along with 20 elements. main should then call populate_array, passing it the pointer and dimension, and finally call find_val, passing it the pointer, array dimension, and a value to search for (use a fixed value of 10). After find_val is called, main should print a cout statement indicating whether the value was found, deallocate the array, then quit. create_array should create a dynamic array of the given dimension. This function should return void. populate_array should fill the array with the first 20, positive integers using a for loop. find_val should search through the array that it is passed for the value that it is also passed. It should return a bool indicating whether or not the value was found. main will either print that the value was found or not, depending on the value it receives from the find_val function (this will be true or false).

So from what I am gathering, I need to create a pointer and then pass it to the create_array function. However, it says that create_array needs to return void. So how would the rest of the program be able to access the created array. Here is what I have so far, and it compiles. But I don't know how to pass it to the next function because it is only defined in create_array:

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

void create_array( int* );
void populate_array( int* );
bool find_val( int* , int );

int main()
{
    int * P;
    int valToFind = 10;
    create_array( P );
    populate_array( P );
    find_val( P, valToFind );
}

void create_array( int * P )
{
    P = new int [20];
}
What about using return values?

1
2
3
4
5
6
7
8
9
// ... before main()
int* create_array();
// ... in main()
int * P = create_array();
// ... under main()
int * create_array()
{
    return new int[20];
}


Ah, just noticed create_array needs to return void.
Damn limitations.

Well, you can still pass a pointer-to-pointer (Head-ache incoming?):

1
2
3
4
5
6
7
8
9
10
11
void create_array( int ** );
// ...
int * P;
create_array(&P); // If (P) is of type int*, then (&P) is of type int**
// ...
void create_array( int ** P )
{
    if(P)
        *P = new int[20]; // Assign a new value to your int*.
    // Because *(&P) equals P
}
Last edited on
Well that's what I wanted to do, because... ya know... that's how a normal person would do it. But the directions explicitly state "create_array should create a dynamic array of the given dimension. This function should return void."

So that is where and why I am stuck.
Edited the post ^^

Making this a good useful post:

Think of a simple...
int C = 0;

"A pointer to C" means the RAM address of the "C" variable.
If you go look deeply into your ram, at the position of "A pointer to C", you will see the C value. (Just as an example).

The type itself of a pointer is:
int * pC = &C;

Examinate the first half of the above statement.
Now, pC is "A pointer to C".
The value of pC will be the RAM position of C.

&C means the actual position in the RAM of the variable C.
Say we want to take the RAM address of variable D, you would write &D instead.

To access that RAM location, you only need to add a * prefix:
*pC = 42;
At this point, also C will be 42, because you changed its content in the ram, using the pointer.

Now, the deal with pointers is no stack overflows and dynamic size of allocation, things that aren't possible without using pointers, so, yes, it's important.

Say you want an array of a size you don't know:

int * P = new int[ MySize ];

Knowing the first part:
The second part (new int //... ) simply means:
Give me an address in the RAM that is not being used and that is big enough.
Reserve its usage to me.

Now this should have done it quite clear.
But one thing happens:
How does your OS know when you're done using your RAM?
Simple: You have to tell him (Something you forgot to do, above).

1
2
3
4
int * P = new int[ MySize ];
// Use *P freely
delete[] P; // This tells your OS to stop reserving this block of memory to you
P = 0; // But you must make sure not to use it anymore. 


Now notice a little difference:

For arrays you do:
1
2
3
4
int * P = new int[ MySize ];
// ...
delete[] P;
P = 0;


But for single objects:
1
2
3
4
int * P = new int;
// ...
delete P; // Don't use [] in delete, if you didn't use [...] in new.
P = 0;


Anymore questions or still need help on the topic, post a reply.
Last edited on
Okay so let me make sure that I am understanding this. The double pointer (**) is so you can prototype out the function. The (&) makes P a ** P which is the address of P, so when P is modified, it is modified outside of just the function. Am I correct in that strange thought process?
I've edited the post above to make it a little pointer guide.

Anyways, P is of type int*.
So, &P becomes of type int**.

JayRyGeo wrote:
so when P is modified, it is modified outside of just the function. Am I correct in that strange thought process?

Halfway.
If you edit P itself INSIDE the function, it will not change.
But in this example we are editing P's POINTED VALUE inside the function.
The POINTED VALUE, in this case, WILL change.
So when I need to pass the next one like this right?

void populate_array( int ** P )

and this will keep me pointed to the *P[20]?

Actually I ran across a problem already. *P[0] is allocated, but *P[1] is not. Am I pointing it wrong?
Last edited on
Well I have my bool statement returning true, so I think I have it.

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

void create_array( int ** );
void populate_array( int * );
bool find_val( int * , int );

int main()
{
    int * P;
    int valToFind = 10;
    bool returnedValue = false;
    create_array( &P );
    populate_array( P );
    returnedValue = find_val( P, valToFind );
    if( returnedValue = true )
    {
        cout << "True!";
    }
}

void create_array( int  ** P )
{
    *P = new int [20];
}

void populate_array( int * P )
{
    for( int i = 0; i < 20; i++)
    {
        P[i] = i;
    }
}

bool find_val( int * P, int val )
{
    bool flag = false;
    int counter = 0;
    while( flag = false )
    {
        if( counter < 20 )
        {
            if( P[ counter ] == val )
            {
                flag = true;
                counter = 20;
            }

            else
            counter++;
        }
    }
    return flag;
}

It's good as example (Besides, you still didn't delete[] your array), but if 'val' is not in the array, an infinite loop happens.
To solve it, change find_val to:
1
2
3
4
5
6
7
8
9
10
11
bool find_val( int * P, int val )
{
    unsigned int i = 0; // i -> index/iterator
    while(i < 20)
    {
        if(P[i] == val)
            return 1;
        ++i;
    }
    return 0;
}

You can see how also the code is shorter.
In fact, there is no need, in this case, to keep track of the return value, or to make so many if's.

Also a little thing you may have missed:
while( flag = false )
Should be
while( flag == false )
Topic archived. No new replies allowed.