Can the object be destroyed earlier, to make its storage memory be reused by subsequent objects?

144 views Asked by At

C++: can the object be destroyed earlier, to make its storage memory be reused by subsequent objects?

In one segment of C++ code, at the 1st half part, objects a, b are used; at the 2nd half part, objects c, d are created and used.

Since objects a, b take a lot of memory, I want to manually destroy objects a, b when the 1st half part finishes.

I know I can use new, delete to achieve it.

But if I do not use new, and still want to destroy objects earlier (that means, before the time of its end of scope), can I manually call its destructor to destroy it? So that part of memory can be reused for object c and d. (I do not need to release the memory since reuse is fine.

Here is a pseudo code:

monsterClass a, b;
dragonClass c, d;
int i,j,k,l;

a = monsterClass(1000, 2000);
b = monsterClass(2000, 3000);
i = processMethod1(a, b);
j = ...;
k = ...;
l = ...;


// here, I want to destroy a, b, since they are not used any more, while occupy memory.
// The above half part and the below half part use many common variables. 
// So it seems scope {} method makes it inconvenient, 
// since I don't want to create a function with too many parameters.
// I don't want to use new or delete here. I hope it looks simple and not prone to error
// So can I use: ~a, ~b here?

c = dragonClass(400, 3000);
d = dragonClass(500, 4000);
processMethod2(c, d, i);
j = ...;
k = ...;
l = ...;

[Update 1] So most people suggest to use scope, which is a good way. I am just still very curious, can I use ~a and ~b there? I think it seems to be a feasible and convenient way, too.

[Update 2] I come up another situation. In this situation, the scopes of different variables are interwined! It is like this: the scope of a has an overlap of scope of b, but they are not including relationship. It is overlap partly relationship. In this case, does this mean using scope is not possible? And the last resort is to use new and delete, right?

4

There are 4 answers

1
timrau On

As your code snippet, you could write as

int i,j,k,l;

{
  monsterClass a(1000, 2000);
  monsterClass b(2000, 3000);
  i = processMethod1(a, b);
  j = ...;
  k = ...;
  l = ...;
}

// here, you want to destroy a, b, since they are not used any more, while occupy memory.

dragonClass c(400, 3000);
dragonClass d(500, 4000);
processMethod2(c, d, i);
j = ...;
k = ...;
l = ...;

// you could use the same technique if there are still e, f or so
2
Cory Kramer On

You can control the lifetime manually of objects on the stack by using braces.

void foo()
{
    int x = 5;
    int y = 2;

    {          // This introduces a new scope
    int z = 3;
    }          // After this brace, z is now out of scope

    int a = x + y;
}

But note that once the variable falls out of scope, when this memory is used again is not specified. Just because I declared another int named a, doesn't mean it will be assigned the address where z used to be.

1
erenon On

Use placement new and call the destructors manually:

{
  char memory[std::max(sizeof(A),sizeof(B))];

  A* pA = new (memory) A();
  // use `pA`
  pA->~A(); // destruct A

  B* pB = new (memory) B();
  // use `pB`
  pB->~B(); // destruct B
} // `memory` goes out of scope

I recommend to read this excellent resource on operator new: http://en.cppreference.com/w/cpp/language/new

3
Mike Seymour On

You could break it down into smaller functions:

void part1() {
    monsterClass a, b;
    a = monsterClass(1000, 2000);
    b = monsterClass(2000, 3000);

    processMethod1(a, b);
}

or blocks within the larger function

{
    monsterClass a, b;
    // and so on
}
{
    dragonClass c, d;
    // and so on
}

or use temporaries

processMethod1(
    monsterClass(1000, 2000);
    monsterClass(2000, 3000);
);

If you're doing something so complicated that none of these are suitable, you could mess around with a union, or placement-new; the details would be fiddly, depending on exactly what your strange requirements are.