Passing Pointers

The coding is about passing pointers for an int and an array.

1. How do you pass the **pointer as a reference into the function and get it to store values in the array?

2. Is line 30, the "delete [] buffer", needed? There is no dynamic memory being created.


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
#include <iostream>

using namespace std;

bool get_data(int *psize, int **pi)
{
	for (int i = 0; i < *psize; ++i)
	{
		if (*psize > 10)
			return false;
		else
		{
			**pi[i] = 2 * i;
			cout << i << endl;
		}
		return true;
	}
}

int main()
{
	int size = 10;
	int *buffer = nullptr;
	if (get_data(&size, &buffer))
	{
		for (int i = 0; i < size; ++i)
		{
			cout << buffer[i] << endl;
		}
		delete [] buffer;
	}

	return 0;
}
That's some really error-ridden code. I sure hope that is only used for teaching purposes, and even then it's so weird.

Anyway....

You're assigning a nullptr to buffer.
As soon as you hit line 13, you are dereferencing a null pointer, and that makes your program undefined behavior (mostly likely violently segfaulting/crashing).

If you want to actually be able to assign values to an array, pass in a pointer to an allocated array.

(1)
1
2
int size = 10;
int* buffer = new int[size];

or

(2)
1
2
const int size = 10; // needs to be const to be used with a static array
int buffer[size];


If you use (1), which is probably what your assignment is looking for, then you need to use delete[].

If you use (2), then you shouldn't use delete[].

Correct,
only delete something created with new.
only delete[] something created with new[].

Also, you don't need to check size every iteration, you can check that at the beginning of the get_data function.
Last edited on
Ganado,

I made the suggested changes, and you're correct that I want to use (1) to use a pointer. However, the program still does not work because there is something wrong with line 11.

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
#include <iostream>

using namespace std;

bool get_data(int *psize, int **pi)
{
	if (*psize > 10)
		return 1;
	for (int i = 0; i < *psize; ++i)
	{
		**pi[i] = 2 * i;
		cout << i << endl;
	}
	return true;
}

int main()
{
	int size = 10;
	int *buffer = new int[size];
	if (get_data(&size, &buffer))
	{
		for (int i = 0; i < size; ++i)
		{
			cout << buffer[i] << endl;
		}
		delete [] buffer;
	}

	return 0;
}
Last edited on
there is something wrong with line 11
**pi[i] = 2 * i;

Too many asterisks.
Also, indirection has a lower precedence than subscript:
http://en.cppreference.com/w/cpp/language/operator_precedence
Is it important for you to pass the size of your C-style array by pointer?

Hints:
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>

bool get_data(int psize, int **pi);
void waitForEnter();

int main()
{
    constexpr int size = 10;
    int *buffer = new int[size];
    if (get_data(size, &buffer))
    {
        for (int i = 0; i < size; ++i) { std::cout << buffer[i] << ' '; }
        std::cout << '\n';
        delete buffer;
    }
    waitForEnter();
    return 0;
}

bool get_data(int psize, int **pi)
{
    if (psize > 10) { return false; }
    for (int i = 0; i < psize; ++i)
    {
        (*pi)[i] = 2 * i;
        std::cout << i << ' ';
    }
    std::cout << '\n';
    return true;
}

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Output:
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18

Press ENTER to continue...

Thank you, Enoizat,

It is not important to pass the size of the array as a pointer. Actually, to keep things simple, it should be a constexpr as you indicated since arrays cannot change size.

The statement int *buffer = new int[size]; creates an array on the free store pointed to by *buffer. The function call to bool get_data is as follows: get_data(int size, &buffer). Since the second parameter in bool get_data is a ** or a pointer to a pointer.

What takes place to convert a pointer (*) to a pointer to a pointer(**)? Secondly, why was delete buffer; used instead of delete [] buffer;?


It should have been delete [] buffer.

What takes place to convert a pointer (*) to a pointer to a pointer(**)?
a type** would be the address of (or, a pointer to) a type*
i.e
A pointer is the address of the data.
A double-pointer is the address of the pointer.

Your program is needlessly using more indirection than needed. Only one level of indirection is needed to pass a 1-dimensional raw 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
#include <iostream>

using namespace std;

// No need to pass the size by pointer; it's not being changed
// No need to pass a double pointer; just pass the pointer to the array
bool get_data(int size, int *pi)
{
	if (size > 10)
		return false; // I assume this is a failing condition, so return false or true (Don't return an integer, this is less clear to the reader)
	
	for (int i = 0; i < size; ++i)
	{
		pi[i] = 2 * i; // the [i] is doing 1 layer of dereferencing; this is all that is needed
		cout << i << endl;
	}
	
	return true;
}

int main()
{
	int size = 10;
	int *buffer = new int[size]; // buffer is already the address pointing to the data you just new'd.
	if (get_data(size, buffer)) // just pass size and buffer, not their addresses
	{
		for (int i = 0; i < size; ++i)
		{
			cout << buffer[i] << endl;
		}
		delete [] buffer;
	}

	return 0;
}
Last edited on
Thank you very much, Ganado! I have a better understanding of the ** or the pointer to pointer.
Registered users can post here. Sign in or register to post.