Object instantiation methods in C++ - c++

What is the difference between these two instantiation and method call types?
Take this code for example:
class Test
{
public:
Test(int nrInstance)
{
std::cout << "Class " << nrInstance << " instanced " << std::endl;
}
~Test() { }
int retornaValue()
{
return value;
}
private:
const int value = 10;
};
int main(int argc, char *argv[])
{
Test *test1 = new Test(1);
Test test2(2);
std::cout << test1->retornaValue() << std::endl;
std::cout << test2.retornaValue() << std::endl;
return 0;
}
From what ive read, using the first way, the variable is allocated in the heap, and the second, in the stack, but arent both inside the Main scope, and being deallocated after the function exits?
Also, calling methods is different in both examples, why?

Your right that both variables are in the Main scope and deallocated after the function exits, but in the first case it is the Test* value that is deallocated, not the Test instance itself. Once the pointer is deallocated, the class instance is leaked. In the second case, the Test instance is on the stack, so the instance itself is deallocated.
Also, calling methods is different in both examples, why?
Unless overloaded, foo->bar is equivalent to (*foo).bar. The calling syntax is different because in the first case, test1 is a pointer to an instance, and in the second, test2 is an instance.

but arent both inside the Main scope, and being deallocated after the
function exits?
No not at all... *test1 will not be deallocated until you call delete on it.

but arent both inside the Main scope, and being deallocated after the function exits?
The stack instance is unwound as the scope is closed, and thus deallocated. The pointer is as well, but the object it points to is not. You must explicitly delete instances allocated with new.

In the first example, you are creating both a pointer to the object on the stack, and the object itself on the heap.
In the second example you are creating the object itself on the stack.
The syntax difference is the difference between calling a function through a pointer and calling it on an object directly.
You are wrong about the first example being cleaned up, you need a delete before the pointer goes out of scope or you have what is known as a memory leak. Memory leaks will be cleaned up by the OS when the program exits, but good practice is to avoid them.

You've clearly stated the difference in your question, one is on the stack, and one is on the heap. And yes, when main() exits, it will be deallocated. Now let's take a different approach.
#include <iostream>
using namespace std;
class MemoryLeak{
private:
int m_instance
public:
MemoryLeak(int i) : m_instance(i)
{ cout << "MemoryLeak " << i << " created.\n"; }
~MemoryLeak() { cout << "MemoryLeak " << m_instance << " deleted.\n"; }
};
void makeMemoryLeak(){
static int instance = 0
MemoryLeak mem1(++instance);
MemoryLeak* mem2 = new MemoryLeak(++instance);
}
int main(){
for(int x = 0; x < 10; ++x){
makeMemoryLeak();
cout << endl;
}
cin.get(); // Wait to close
return 0;
}
You will see 20 "New MemoryLeak created." lines but only 10 "MemoryLeak deleted" lines. So those other 10 instances are still in memory until you close the program. Now let's say that that program never shuts down, and MemoryLeak has a size of 20 bytes. and makeMemoryLeak() runs once a minute. After one day, or 1440 minutes, you'll have 28.125 kb of memory that is taken up, but you have no way to access.
The solution would be to change makeMemoryLeak()
void makeMemoryLeak(){
MemoryLeak mem1;
MemoryLeak* mem2 = new MemoryLeak();
delete mem2;
}

Regarding what gets created and destroyed:
struct Test {};
void func()
{
// instantiate ONE automatic object (on the stack) [test1]
Test test1;
// Instantiate ONE automatic object (on the stack) [test2]
// AND instantiate ONE object from the free store (heap) [unnamed]
Test* test2 = new Test; // two objects!!
} // BOTH automatic variables are destroyed (test1 & test2) but the
// unnamed object created with new (that test2 was pointing at)
// is NOT destroyed (memory leak)

if you dont delete Test1 (Test*) before coming out of main, it will cause memory leak.

Related

How to observe c++ destructor destroys basic data types?

I have two classes one is main and other is Test, for the Test class, I have Test.cpp and Test.h
//-----Test.h--------//
#pragma once
class Test
{
private:
int num;
public:
Test(void);
Test(int n);
~Test(void);
};
//------Test.cpp------//
#include "Test.h"
#include<iostream>
using namespace std;
Test::Test(void)
{
}
Test::Test(int n)
{
num = n;
}
Test::~Test(void)
{
cout << "Deleted" << endl;
cout << "num = " << num << endl ;
}
//---------main.cpp--------------//
#include "Test.h"
#include<iostream>
using namespace std;
int main()
{
Test t1 = Test(5);
return 0;
}
The output which I have expected is
Deleted
num = 0
But Real Output is
Deleted
num = 5
Why this occurs, why destructor, dint free the memory
or dint delete the basic data type, How can I delete the variable,
Using what method I can observe basic datatype getting deleted?
Destruction of an object does not mean setting values to zero. That would be unnecessary work. Rather, all that is required is that resources be released. Bits are typically left as-is (representing 5 in your example) unless there is a compelling reason to do otherwise.
Furthermore, members are destroyed after the class. In your example, first ~Test() is run to destroy t1, then t1.num would be destroyed. The destructor of Test cannot view the destruction of Test::num.
why destructor, dint free the memory or dint delete the basic data type
You did not have any memory allocated in the heap, so there is no need to free anything.
All you have is a basic type int which does not need any memory deallocation.
If instead you had some pointer member variable:
private:
int* num;
and you allocated it somewhere in your constructor: new int(6); then sure you must deallocate/free it inside your destructor.
In this case, probably a shared-pointer may help, which automatically is destroyed just after the destructor:
std::shared_ptr<int> num;
But it has to be constructed, in the constructor you need:
Test::Test(int n)
: num(std::make_shared<int>(n)
{
// *n == 100
}
To see if the data is deleted use Valgrind.

Deleting objects in C++ explicitly

I have a class myclass.
In the main function, I create objects of type myclass in every iteration and want to delete them after each iteration. I have not created the objects dynamically. Can I delete the them explicitly because I don't need them after the iteration gets over.
class myclass{
int value;
void do_function();
};
int main()
{
for(int i=0;i<count;i++)
{
myclass obj;
obj.do_function();
}
}
The object obj is not needed after one iteration, but the memory is still there. How can I free that memory?
You don't have to delete them explicitly, because as you have created them myclass obj; they are created on stack and deleted after each iteration.
When the program reaches the first curly brace after the instantiation on stack of an object it deletes it, in your case:
myclass obj;
obj.do_function();
} // Here the obj is deleted
Here are some examples and explanations of how stack is working, versus heap, to let you understand better when you need to free memory yourself, and when you don't.
Note: I have used notions of stack and heap only to suggest how objects are handled relatively to their lifetime like when an object from stack should be freed after it leaves the scope, and an object of heap lives until it's explicitly freed. As mentioned in comments, these notions are not considered in standard C++ because the programs can run in an environment which does not support these type of memory. Although the compiler respects these rules for a C++ program.
myclass obj; will already be deleted automatically after each iteration of the loop.
How can I free that memory?
You don't need to.
Short answer is that you don't need to.
Here's a quick example:
class myClass {
public:
myClass() { cout << "Hello!" << endl; }
~myClass() { cout << "Goodbye!" << endl; }
void do_function() { cout << "Something" << endl; }
};
int main() {
for (int i=0; i<3; ++i) {
myClass obj;
obj.do_function();
}
}
Output:
Hello!
Something
Goodbye!
Hello!
Something
Goodbye!
Hello!
Something
Goodbye!
You are allocating obj on the stack. Whenever your program goes out of scope, the memory automatically gets released from the stack.
You create a scope for every iteration of a for loop. Or the inner curly brace:
for (int i=0; i<3; ++i) { <-- Right there
And obj goes out of scope:
obj.do_function();
} <-- Right here
If you don't create an object dynamically, the object is created on stack and it is deleted when the closing bracket, that defines its scope, is seen. You can have your own opening and closing brackets to restrict the scope of a variable. This would be helpful to just free memory from unnecessary variables. For example
for(...)
{
//do something
{
myclass obj;
/// use obj here
}//obj is deleted from stack
//do something which doesnt require myclass obj
}

Is it okay to give a stack object address to placement new?

Ignoring usefulness of such practice. (Though real-life examples are welcome, of course.)
For example, the following program outputs the correct value for a:
#include <iostream>
using namespace std;
int main()
{
int a = 11111;
int i = 30;
int* pi = new (&i) int();
cout << a << " " << endl;
}
But isn't new-allocation supposed to create some bookkeeping information adjacent to i (for correct subsequent deallocation), which in this case is supposed to corrupt the stack around i?
Yes, it's perfectly OK to perform placement-new with a pointer to an object on the stack. It will just use that specific pointer to construct the object in. Placement-new isn't actually allocating any memory - you have already provided that part. It only does construction. The subsequent deletion won't actually be delete - there is no placement delete - since all you need to do is call the object's destructor. The actual memory is managed by something else - in this case your stack object.
For example, given this simple type:
struct A {
A(int i)
: i(i)
{
std::cout << "make an A\n";
}
~A() {
std::cout << "delete an A\n";
}
int i;
};
The following is completely reasonable, well-behaved code:
char buf[] = {'x', 'x', 'x', 'x', 0};
std::cout << buf << std::endl; // xxxx
auto a = new (buf) A{'a'}; // make an A
std::cout << a->i << std::endl; // 97
a->~A(); // delete an A
The only case where this would be invalid would be if your placement-new-ed object outlasts the memory you new-ed it on - for the same reason that returning a dangling pointer is always bad:
A* getAnA(int i) {
char buf[4];
return new (buf) A(5); // oops
}
Placement new constructs the element in place and does not allocate memory.
The "bookkeeping information" in this case is the returned pointer which ought to be used to destroy the placed object.
There is no delete associated with the placement since placement is a construction. Thus, the required "clean up" operation for placement new is destruction.
The "usual steps" are
'Allocate' memory
Construct element(s) in place
Do stuff
Destroy element(s) (reverse of 2)
'Deallocate' memory (reverse of 1)
(Where memory can be stack memory which is neither required to be explicitly allocated nor deallocated but comes and goes with a stack array or object.)
Note: If "placing" an object into memory of the same type on the stack one should keep in mind that there's automatic destruction at the end of the object's lifetime.
{
X a;
a.~X(); // destroy a
X * b = new (&a) X(); // Place new X
b->~X(); // destroy b
} // double destruction
No, because you don't delete an object which has been placement-newed, you call its destructor manually.
struct A {
A() { std::cout << "A()\n"; }
~A() { std::cout << "~A()\n"; }
};
int main()
{
alignas(A) char storage[sizeof(A)];
A *a = new (storage) A;
std::cout << "hi!\n";
a->~A();
std::cout << "bye!\n";
}
Output:
A()
hi!
~A()
bye!
In your case, there's no need to call a destructor either, because int is trivially-destructible, meaning that its destructor would be a no-op anyway.
Beware though not to invoke placement-new on an object that is still alive, because not only will you corrupt its state, but its destructor will also be invoked twice (once when you call it manually, but also when the original object should have been deleted, for exampel at the end of its scope).
Placement new does construction, not allocation, so there's no bookkeeping information to be afraid of.
I can at the moment think of one possible use case, though it (in this form) would be a bad example of encapsulation:
#include <iostream>
using namespace std;
struct Thing {
Thing (int value) {
cout << "such an awesome " << value << endl;
}
};
union Union {
Union (){}
Thing thing;
};
int main (int, char **) {
Union u;
bool yes;
cin >> yes;
if (yes) {
new (&(u.thing)) Thing(42);
}
return 0;
}
Live here
Though even when the placement new is hidden in some member function, the construction still happens on the stack.
So: I didn't look in the standard, but can't think of why placement new on the stack shouldn't be permitted.
A real world example should be somewhere in the source of https://github.com/beark/ftl ... in their recursive union, which is used for the sum type.

Can someone explain exactly what happens if an exception is thrown during the process of allocating an array of objects on the heap?

I defined a class foo as follows:
class foo {
private:
static int objcnt;
public:
foo() {
if(objcnt==8)
throw outOfMemory("No more space!");
else
objcnt++;
}
class outOfMemory {
public:
outOfMemory(char* msg) { cout << msg << endl;}
};
~foo() { cout << "Deleting foo." << endl; objcnt--;}
};
int foo::objcnt = 0;
And here's the main function:
int main() {
try {
foo* p = new foo[3];
cout << "p in try " << p << endl;
foo* q = new foo[7];
}catch(foo::outOfMemory& o) {
cout << "Out-of-memory Exception Caught." << endl;
}
}
It is obvious that the line "foo* q = new foo[7];" only creates 5 objects successfully, and on the 6th object an Out-of-memory exception is thrown. But it turns out that there's only 5 destructor calls, and destrcutor is not called for the array of 3 objects stored at the position p points to. So I am wondering why? How come the program only calls the destructor for those 5 objects?
The "atomic" C++ allocation and construction functions are correct and exception-safe: If new T; throws, nothing leaks, and if new T[N] throws anywhere along the way, everything that's already been constructed is destroyed. So nothing to worry there.
Now a digression:
What you always must worry about is using more than one new expression in any single unit of responsibility. Basically, you have to consider any new expression as a hot potato that needs to be absorbed by a fully-constructed, responsible guardian object.
Consider new and new[] strictly as library building blocks: You will never use them in high-level user code (perhaps with the exception of a single new in a constructor), and only inside library classes.
To wit:
// BAD:
A * p = new A;
B * q = new B; // Ouch -- *p may leak if this throws!
// Good:
std::unique_ptr<A> p(new A);
std::unique_ptr<B> q(new B); // who cares if this throws
std::unique_ptr<C[3]> r(new C[3]); // ditto
As another aside: The standard library containers implement a similar behaviour: If you say resize(N) (growing), and an exception occurs during any of the constructions, then all of the already-constructed elements are destroyed. That is, resize(N) either grows the container to the specified size or not at all. (E.g. in GCC 4.6, see the implementation of _M_fill_insert() in bits/vector.tcc for a library version of exception-checked range construction.)
Destructors are only called for the fully constructed objects - those are objects whose constructors completed normally. That only happens automatically if an exception is thrown while new[] is in progress. So in your example the destructors will be run for five objects fully constructed during q = new foo[7] running.
Since new[] for the array that p points to completed successfully that array is now handled to your code and the C++ runtime doesn't care of it anymore - no destructors will be run unless you do delete[] p.
You get the behavior you expect when you declare the arrays on the heap:
int main()
{
try
{
foo p[3];
cout << "p in try " << p << endl;
foo q[7];
}
catch(foo::outOfMemory& o)
{
cout << "Out-of-memory Exception Caught." << endl;
}
}
In your code only the pointers were local automatic variables. Pointers don't have any associated cleanup when the stack is unwound. As others have pointed out this is why you generally do not have RAW pointers in C++ code they are usually wrapped inside a class object that uses the constructor/destructor to control their lifespan (smart pointer/container).
As a side note. It is usually better to use std::vector than raw arrays (In C++11 std::array is also useful if you have a fixed size array). This is because the stack has a limited size and these object puts the bulk of the data in the heap. The extra methods provided by these class objects make them much nicer to handle in the rest of your code and if you absolutely must have an old style array pointer to pass to a C function they are easy to obtain.
int main()
{
try
{
std::vector<foo> p(3);
cout << "p in try " << p << endl;
std::vector<foo> q(7);
// Now you can pass p/q to function much easier.
}
catch(foo::outOfMemory& o)
{
cout << "Out-of-memory Exception Caught." << endl;
}
}

C++ basics, vectors, destructors

I'm a little confused about the best practice for how to do this. Say I have a class that for example allocs some memory. I want it to self destruct like an auto but also put it in a vector for some reason unknown.
#include <iostream>
#include <vector>
class Test {
public:
Test();
Test(int a);
virtual ~Test();
int counter;
Test * otherTest;
};
volatile int count = 0;
Test::Test(int a) {
count++;
counter = count;
std::cout << counter << "Got constructed!\n";
otherTest = new Test();
otherTest->counter = 999;
}
Test::Test() {
count++;
counter = count;
std::cout << counter << "Alloced got constructed!\n";
otherTest = NULL;
}
Test::~Test() {
if(otherTest != 0){
std::cout << otherTest->counter << " 1Got destructed" << counter << "\n";
otherTest->counter = 888;
std::cout << otherTest->counter << " 2Got destructed" << counter << "\n";
}
}
int vectorTest(){
Test a(5);
std::vector<Test> vecTest;
vecTest.push_back(a);
return 1;
}
int main(){
std::cout << "HELLO WORLD\n";
vectorTest();
std::cout << "Prog finished\n";
}
In this case my destructor gets called twice all from counter 1, the alloc' object has already been set to 888 (or in a real case freed leading to bad access to a deleted object). What's the correct case for putting a local variable into a vector, is this some kind of design that would never happen sensibly. The following behaves differently and the destructor is called just once (which makes sense given its an alloc).
int vectorTest(){
//Test a(5);
std::vector<Test> vecTest;
vecTest.push_back(*(new Test(5)));
return 1;
}
How can I make the local variable behave the same leading to just one call to the destructor? Would a local simply never be put in a vector? But aren't vectors preferred over arrays, what if there are a load of local objects I want to initialize separately and place into the vector and pass this to another function without using free/heap memory? I think I'm missing something crucial here. Is this a case for some kind of smart pointer that transfers ownership?
A vector maintains its own storage and copies values into it. Since you did not implement a copy constructor, the default one is used, which just copies the value of the pointer. This pointer is thus deleted twice, once by the local variable destructor and once by the vector. Don't forget the rule of three. You either need to implement the copy and assignment operators, or just use a class that already does this, such as shared_ptr.
Note that this line causes a memory leak, since the object you allocated with new is never deleted:
vecTest.push_back(*(new Test(5)));
In addition to what Dark Falcon wrote: To avoid reallocating when inserting into a vector, you typically implement a swap function to swap local element with a default-constructed one in the vector. The swap would just exchange ownership of the pointer and all will be well. The new c++0x also has move-semantics via rvalue-references to help with this problem.
More than likely, you'd be better off having your vector hold pointers to Test objects instead of Test objects themselves. This is especially true for objects (like this test object) that allocate memory on the heap. If you end up using any algorithm (e.g. std::sort) on the vector, the algorithm will be constantly allocating and deallocating memory (which will slow it down substantially).