problem understanding the heap memory

i recently started learning about the new and the delete keywords.

from what i understand you use the new to create a variable on the heap memory and delete to free up the allocated memory

is my hypothesis correct?

can someone point out my mistakes in the following 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
28
29
30
31
32
33
34
35
#include <tuple>
#include <iostream>

using std::make_tuple, std::tuple, std::get;

class myClass {
private:
        int integer = 0;
public:
        myClass(){}
        myClass(int i) {integer = i;}
        int getInt() {return integer;}
};

tuple<int*, myClass*>* myFunc() {
        myClass *c1 = new myClass;
        int *integer = new int;
        for(int i = 0; i <= 10; i++) {
                c1[i] = myClass(i);
                *integer = i;
        }
        auto myTup = make_tuple(integer, c1);
        auto* myTupP = &myTup;
        return myTupP;
}

int main() {
        auto myTuple = new tuple<int*, myClass*>;
        myTuple = myFunc();
        std::cout << get<1>(*myTuple)[1].getInt() << std::endl;
        std::cout << get<0>(*myTuple) << std::endl;
        // will that delete the contents of "myTuple" as well?
        delete myTuple;
        return 0;
}
Last edited on
Some refer to the dynamic memory resource as "Free Store". It may be a heap. (There can be more than one heap in a system.)


The new and delete do more than just allocate and deallocate block of raw memory.
They also construct and deconstruct objects within that block.

Placement new does not even allocate the memory, but construct object into given space.


The delete myTuple; thus invokes the destructor of tuple<int*,myClass*> first and then deallocates the memory block.


The answer to
// will that delete the contents of "myTuple" as well?

depends thus on the destructor of std::tuple. I'd say "no".
Technically, the "content" of "myTuple" is just two pointers and trivial destruction of pointer is a no-op.


There is both new that creates one object and array new that creates an array of objects. You cannot mix the two and have to use corresponding delete too (for single or for array). You make the error of creating one object but assuming that you have an array.


Automatic variables, variables declared within a (function) scope, have memory allocated from stack on call of the function/entry to scope and are automatically destroyed and deallocated at end of the scope. You return an address of automatic variable from function.


You change a pointer to point from one object to an another. You can't access the first object after that.


Assignment is not initialization. Not an error here, but a bad habit.
c1 is allocated space for 1 element of myClass. Hence c1[i] is invalid for i > 0.

myTup is local to the function and doesn't exist outside. Hence a pointer to myTup is only valid within the function. Thus returning a pointer to a local variable is not correct as it refers to memory that is no longer used once the function returns.

Perhaps something like (as C++17):

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

using std::make_tuple, std::tuple, std::get;

class myClass {
private:
	int integer {};
public:
	myClass() {}
	myClass(int i) : integer(i) {}
	int getInt() const { return integer; }
};

auto myFunc() {
	const auto c1 {new myClass[10]};
	const auto pint {new int};

	for (int i = 0; i < 10; ++i) {
		c1[i] = myClass(i);
		*pint= i;
	}

	return new tuple {pint, c1};
}

int main() {
	auto myTuple {myFunc()};

	const auto pint {get<0>(*myTuple)};
	const auto Pclass {get<1>(*myTuple)};

	std::cout << Pclass[1].getInt() << '\n';
	std::cout << *pint << '\n';

	delete pint;
	delete[] Pclass;
	delete myTuple;
}


Last edited on
One more thing:
1
2
3
4
5
6
7
8
const auto pint {new int};
for ( int i = 0; i < 10; ++i ) {
    *pint = i;
}

// OR

const auto pint { new int {9} };
Topic archived. No new replies allowed.