Memory leakage avoidance when using new[]

B

Barry

Hi there,

I've learned from experience to use an auto_ptr instead of a raw
pointer for my class variables, as follows -

class Person
{
public:
Person(const bool isSingle=true):lover(isSingle?0:new Lover() ){}
private:
const auto_ptr<Lover> lover;
}

since its a very good approach to avoiding memory leaks.

But what about when that pointer points to memory allocated using new
[]?

private:
const auto_ptr<Lover> lover;
const Offspring* offspring;
const CompirerErrors* compirerErrors;

how would you normally deal with such a case with regard to avoiding
memory leaks?

For example -

Person me;
Person imposter;
imposter = me;

might leak when operator=() throws - when calling new, or when
assigning each member of offspring and compirerErrors.

Therefore how should I implement operator=()? How about this as a
generic solution to memory leakage in operator=()?

Person& operator=(const Person& person)
{
if(person==this)
return this;

try
{
Offspring* tempOffspring = new Offspring[noOfOffspring];
CompirerErrors* tempCompirerErrors = new CompirerErrors
[noOfCompilerErrors];

for(int i = 0; i<noOfOffspring;i++)
tempOffspring = person.tempOffspring;

for(int i = 0; i<noOfCompilerErrors;i++)
tempCompirerErrors = person.compirerErrors;
}
catch(...)
{
delete [] tempOffspring;
delete [] noOfOffspring;

throw PersonException();
}

offspring = tempOffspring;
compirerErrors = tempCompirerErrors;

...
}
 
J

Juha Nieminen

Barry said:
But what about when that pointer points to memory allocated using new
[]?

It depends on the copying policy you want to use.

If copying is disabled, or if a deep copy is always performed, just
use std::vector. No need to reinvent the wheel.

If you want the array to be shared, I think there's a smart pointer
for that purpose in the boost library. You could relatively easily code
one yourself.

If you want the ownership to be transferred, implement your own
auto_array (if you google that name you'll probably find implementations
made by others).

If you want copy-on-write, then you'll have to implement that yourself.
 
B

Barry

Barry said:
But what about when that pointer points to memory allocated using new
[]?

It depends on the copying policy you want to use.

If copying is disabled, or if a deep copy is always performed, just
use std::vector. No need to reinvent the wheel.

If you want the array to be shared, I think there's a smart pointer
for that purpose in the boost library. You could relatively easily code
one yourself.

If you want the ownership to be transferred, implement your own
auto_array (if you google that name you'll probably find implementations
made by others).

If you want copy-on-write, then you'll have to implement that yourself.

Thanks for your reply. Since I'm still learning, does the code I
provided in my first post avoid memory leakage? I had taught about
using std::vector actually in this fashion -

private:
std::vector<Offspring> offspring;
std::vector<CompirerErrors> compirerErrors;

...


Person& operator=(const Person& person)
{
if(person==this)
return this;

try
{
tempPerson.offspring = person.tempOffspring;
compirerErrors = person.compirerErrors;
}
catch(...)
{
throw PersonException();
}
...
}

But if -

tempPerson.offspring = person.tempOffspring

were to throw an exception here, wouldn't I end up with a Person
object which is in a corrupt state? How should I deal with this.

Thanks again,

Barry
 
R

red floyd

Barry said:
But what about when that pointer points to memory allocated using new
[]?
  It depends on the copying policy you want to use.
  If copying is disabled, or if a deep copy is always performed, just
use std::vector. No need to reinvent the wheel.
  If you want the array to be shared, I think there's a smart pointer
for that purpose in the boost library. You could relatively easily code
one yourself.
  If you want the ownership to be transferred, implement your own
auto_array (if you google that name you'll probably find implementations
made by others).
  If you want copy-on-write, then you'll have to implement that yourself.

Thanks for your reply. Since I'm still learning, does the code I
provided in my first post avoid memory leakage? I had taught about
using std::vector actually in this fashion -

private:
 std::vector<Offspring> offspring;
 std::vector<CompirerErrors> compirerErrors;

 ...

Person& operator=(const Person& person)
{
  if(person==this)
    return this;

  try
  {
    tempPerson.offspring = person.tempOffspring;
    compirerErrors = person.compirerErrors;
  }
  catch(...)
  {
    throw PersonException();
  }
  ...

}

But if -

 tempPerson.offspring = person.tempOffspring

were to throw an exception here, wouldn't I end up with a Person
object which is in a corrupt state? How should I deal with this.

copy and swap paradigm.
 
D

Daniel Pitts

Sam said:
Barry said:
But what about when that pointer points to memory allocated using new
[]?

private:
const auto_ptr<Lover> lover;
const Offspring* offspring;
const CompirerErrors* compirerErrors;

how would you normally deal with such a case with regard to avoiding
memory leaks?

Very simple: I would not use new, unless absolutely necessary.

I'd estimate that 90% of the time, explicit memory
allocation/deallocation can be replaced with containers.

I've taken over countless projects that leaked memory like a sieve.
Although, after a careful inspection, the memory leaks were obvious, and
the fixes were also obvious, I usually defenestrated the whole mess and
replaced the brain-dead contain with clean usage of STL containers.

I always run into issues with polymorphic objects when I go that route.
Perhaps I should use a pimpl approach?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top