C++ pointers

Pages: 12
Hello, my professor gave me this code and asked me to run it, but before that she said that I must remove all the asterisks in the codes and instruct me to use "typedef int* IntPtr" (idk what it is, i think its a library?) instead, by doing that she said that these codes will still run even if the asterisks are removed in the codes.

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

int main()
{
    int *p1, *p2;

    p1 = new int;
    *p1 = 42;
    p2 = p1;

    cout << "*p1 == " << *p1 << endl;
    cout << "*p2 == " << *p2 << endl;
    *p2 = 53;
    cout << "*p1 == " << *p1 << endl;
    cout << "*p2 == " << *p2 << endl;
    p1 = new int;
    *p1 = 88;
    cout << "*p1 == " << *p1 << endl;
    cout << "*p2 == " << *p2 << endl;


   return 0;
}
Last edited on
typedef just creates an alternative name for a type.

 
typedef int* Ptr;

After this line of code you can write Ptr to denote the int* type.
Last edited on
I tried this but it says redeclaration of 'int* p1 & p2'. Assuming all lines that has IntPtr contains asterisks before. (replaced).

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>
typedef int* IntPtr;
using namespace std;

int main()
{
   IntPtr p1, p2;

    p1 = new int;
    IntPtr p1 = 42;
    p2 = p1;

    cout << "*p1 == " << IntPtr p1 << endl;
    cout << "*p2 == " << IntPtr p2 << endl;
    IntPtr p2 = 53;
    cout << "*p1 == " << IntPtr p1 << endl;
    cout << "*p2 == " << IntPtr p2 << endl;
    p1 = new int;
    IntPtr p1 = 88;
    cout << "*p1 == " << IntPtr p1 << endl;
    cout << "*p2 == " << IntPtr p2 << endl;

   return 0;
}
Line 7 is correct. Are you sure this wasn't the only line where your professor wanted you to remove all asterisks?

The typedef won't help you remove the asterisks on the other lines. For that you would have to rewrite the code to not use pointers, or write a function that dereference the pointer and returns the result and call that in main instead (you would still have to use the asterisk inside the function definition).
Last edited on
Ohh I see, I've been working on this for 3days. Could you fix this codes using typedef? I would like to see an example. Thanks mate :D
No, I can't remove all asterisks by only using typedef.

That's why I'm wondering if you have understood what your professor has asked you to do correctly. Are you sure she didn't just want you to remove the asterisks from line 7?
Removing all asterisks is of course possible, but not sure that's what your professor intended...

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main()
{
    cout << "*p1 == " << 42 << endl;
    cout << "*p2 == " << 42 << endl;
    ...

Or maybe this is it. She just want you to step through the code in your head and replace everything with fixed values? That would force you to think about what is happening and hopefully learn more compared to if you had just ran the program and looked at the output.
Last edited on
The instructions don't really make sense - as * is used in C++ for memory de-referencing. I suggest this is checked... Although * can be replaced with [0] to treat the memory pointer as a pointer to memory 'array' with 1 element. If this is what is meant this should have been made more clear as to requirements.

Also, in C++ using is usually used instead of typedef.

When memory has been allocated via new, it should be freed by using delete.

For the closest to not using * consider:

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

//typedef int* IntPtr;
using IntPtr = int*;

int main() {
	IntPtr p1 { new int { 42 } };
	IntPtr p2 { p1 };

	std::cout << "*p1 == " << 42 << '\n';
	std::cout << "*p2 == " << 42 << '\n';

	*p2 = 53;    // Needed to change the contents of the memory pointed to by p2
        //p2[0] = 53;    // If this is what is wanted... Who knows?
	std::cout << "*p1 == " << 53 << '\n';
	std::cout << "*p2 == " << 53 << '\n';

	p1 = new int {88};
	std::cout << "*p1 == " << 88 << '\n';
	std::cout << "*p2 == " << 53 << '\n';

	delete p1;
	delete p2;
}



*p1 == 42
*p2 == 42
*p1 == 53
*p2 == 53
*p1 == 88
*p2 == 53

Last edited on
You can use [] instead of *.
cout << p1[0]
is the same as
cout << *p1

but who knows if this is what they want. You could ask your prof maybe?
I have no idea what they are trying to teach you here. The original code is more C than c++, leaks memory (line 17), encourages you to do something ugly (typedefs and usings should not rename basic types: use the C++ name so everyone can understand what it is) and has an unclear request that, even if we understand it, is not really driving home any kind of useful core concept.

I recommend you study learncpp.com to supplement this course, when you get a chance.
Thanks everyone for the comments and helpful information you gave to me.
jonnin wrote:
leaks memory (line 17)

Actually, it doesn't.
leaks memory (line 17)


No - as p2 is now pointing to the memory allocated for p1. If p1 and p2 memory is now deleted (as per my code above) then there is no memory leak.
The original code does leak memory. It uses new twice without using delete.
Yes, it should use delete and obviously that is a good habit to get into.

But it doesn't leak memory, because the original memory allocated to p1 is still addressable via p2. The same use of new with pointers would arise if you were constructing a forward list and using new with the head pointer all the time.


Part of the issues with * arises because it is used both in the type declaration AND as a dereferencing operator in c++. Other languages use pointers as an alias and don't require a separate dereferencing operator.
Last edited on
lastchance wrote:
it doesn't leak memory, because the original memory allocated to p1 is still addressable via p2.

But it will be leaked at the end of main, when both p1 and p2 go out of scope. You might not think of this as a problem but I would still consider it to be a memory leak although not on line 17 obviously.
It's a matter of definition. For the duration of the original program the heap memory used remains accessible, so I don't regard it as a memory leak. It will be handed back to the operating system when the program ends.

Clearly it is good practice to have "one new - one delete". (But I don't always clear my linked lists after creating them. As long as they don't continually accumulate memory I let sleeping dogs lie.)
Last edited on
But isn't the "duration of the program" continuing after main() has ended for a little while, to clear up static vars, run functions passed to std::atexit, etc.?

Anyway, I can see how leaking might be used as an "optimization" but the disadvantage is that it makes it harder to find the real leaks when using a memory leak detection tool such as valgrind.
Well, the definition of "memory leak" has been a source of contention before!
https://stackoverflow.com/questions/312069/the-best-memory-leak-definition

IMO some of those answers are "leaking" into the valley of "best practice", rather than strictly defining memory leaks.

I certainly wouldn't use deliberate leaking as an "optimisation", but if "delete" is only going to appear as the last lines of a program - and any future editing of that program isn't likely to change that - then I don't always bother to put them there.
Most modern non-embedded os's free all allocated resources when a program terminates (including memory). So in most cases you do not actually have to free allocated memory before the program exists if it is not required to delete this memory elsewhere in the program. However I contend that it is good practice to do so. Program analysers can squawk if it doesn't and memory errors can be reported on delete. If the delete isn't present and the OS is reliant to delete it can be more difficult to trace a memory error. Also IMO it's a good habit to get into to always delete allocated memory - and not rely/assume about the OS.

Of course, in modern C++ you'd probably use std::unique_ptr/std::shared_ptr instead of new/delete, wouldn't you, in which the issue doesn't arise...
Last edited on
It is a leak as far as this program is concerned; there is nothing contentious about that.

Whether the operating environment cleans up when the sloppy program exits depends: on almost all hosted environments, it would; on many freestanding implementations it won't.
Pages: 12