Weird leak at operator=

  • Thread starter Lucas Kanebley Tavares
  • Start date
L

Lucas Kanebley Tavares

Hello all,

I have a templatized class which has an attribute as: "T *data", all
constructors initialize it to zero, and then allocate memory for the
array (and that IS done correctly, I've checked).

What I find it strange, is that at one point I have to reallocate the
data, but if I put this in my operator= overload:

if (data != 0) delete data; //mem leak here
data = new T[get_data_size()];

valgrind acuses a memory leak, but I've watched my destructor and
unless I do this there, that memory block is NEVER deallocated (and no
it's not a self-assignment issue, that's taken care of, and the other
object is not the same).

I wonder what is going on. Any thoughts?

Thanks!

Lucas Kanebley Tavares

PS: This is more of a curiosity, to me the program seems fine, and it
has never crashed before, so I take it the deallocation is correct...
just weird...
 
L

Lucas Kanebley Tavares

Hello all,

I have a templatized class which has an attribute as: "T *data", all
constructors initialize it to zero, and then allocate memory for the
array (and that IS done correctly, I've checked).

What I find it strange, is that at one point I have to reallocate the
data, but if I put this in my operator= overload:

if (data != 0) delete data; //mem leak here
data = new T[get_data_size()];

valgrind acuses a memory leak, but I've watched my destructor and
unless I do this there, that memory block is NEVER deallocated (and no
it's not a self-assignment issue, that's taken care of, and the other
object is not the same).

I wonder what is going on. Any thoughts?

Thanks!

Lucas Kanebley Tavares

PS: This is more of a curiosity, to me the program seems fine, and it
has never crashed before, so I take it the deallocation is correct...
just weird...

Nevermind, sorry to bother you guys, after hours looking at it, I
stepped away for a minute and saw the missing brackets.. *sigh*
Thank you all, and sorry about the inconvenience.

Lucas Kanebley Tavares
 
T

Thomas J. Gritzan

You don't need to check for 0, because deletion of a null-pointer is a
no-op.
data = new T[get_data_size()];

valgrind acuses a memory leak, [...]

Nevermind, sorry to bother you guys, after hours looking at it, I
stepped away for a minute and saw the missing brackets.. *sigh*
Thank you all, and sorry about the inconvenience.

You could use a std::vector<T> instead of a T*, so your class would
automatically be exception safe, copyable and assignable etc. without a
need to implement operator= and the copy constructor yourself.
 
L

Lucas Kanebley Tavares

You don't need to check for 0, because deletion of a null-pointer is a
no-op.
data = new T[get_data_size()];
valgrind acuses a memory leak, [...]
Nevermind, sorry to bother you guys, after hours looking at it, I
stepped away for a minute and saw the missing brackets.. *sigh*
Thank you all, and sorry about the inconvenience.

You could use a std::vector<T> instead of a T*, so your class would
automatically be exception safe, copyable and assignable etc. without a
need to implement operator= and the copy constructor yourself.

Thanks for the tip, but it's actually an implementation of a "low-
diagonal" matrix, with a weird growth rate, so that wouldn't work.
Well, I guess it would... but still... =/

Let me clarify. This is what the matrix is supposed to look like:
0
0 0
0 0 0
0 0 0 0
Only the value below the main diagonal are used. But it's not only
that, it could grow at a rate of 2 (or any number of) columns per row
(determined upon allocation), as such:
0
0 0 0
0 0 0 0 0
0 0 0 0 0 0 0
...
So, an implementation using vector would get boring FAST. heh

Thanks for the tip, though!

Lucas
 
A

acehreli

You could use a std::vector<T> instead of a T*, so your class would
automatically be exception safe, copyable and assignable etc. without a
need to implement operator= and the copy constructor yourself.

If that vector is the only member, yes it would be exception safe.
Introduce a new member and now the compiler generated assignment
operator is not exception safe. :(

The reason is, it recursively assigns bases and members and can stop
early due to an exception, at which point we would have a partially-
assigned object at hand.

Guideline #N - Observe The Rule of The Big One: Either write the
canonical form of the assignment operator (the one that uses the swap
idiom), or declare the assignment operator private.

Ali
 
L

Lionel B

Lucas said:
I have a templatized class which has an attribute as: "T *data", all
constructors initialize it to zero, and then allocate memory for the
array (and that IS done correctly, I've checked).
What I find it strange, is that at one point I have to reallocate
the data, but if I put this in my operator= overload:
if (data != 0) delete data; //mem leak here

You don't need to check for 0, because deletion of a null-pointer is a
no-op.
data = new T[get_data_size()];
valgrind acuses a memory leak, [...]
Nevermind, sorry to bother you guys, after hours looking at it, I
stepped away for a minute and saw the missing brackets.. *sigh* Thank
you all, and sorry about the inconvenience.

You could use a std::vector<T> instead of a T*, so your class would
automatically be exception safe, copyable and assignable etc. without a
need to implement operator= and the copy constructor yourself.

Thanks for the tip, but it's actually an implementation of a "low-
diagonal" matrix, with a weird growth rate, so that wouldn't work. Well,
I guess it would... but still... =/

Are you aware that std::vector has a `resize()' member that will, if
necessary, do pretty much what your code does: delete and reallocate if
the vector has to grow? It probably also has a much cleverer memory
allocation scheme than you are likely to implement yourself.
Let me clarify. This is what the matrix is supposed to look like: 0
0 0
0 0 0
0 0 0 0
Only the value below the main diagonal are used. But it's not only that,
it could grow at a rate of 2 (or any number of) columns per row
(determined upon allocation), as such: 0
0 0 0
0 0 0 0 0
0 0 0 0 0 0 0
...
So, an implementation using vector would get boring FAST. heh

Boring?!? If boring == safer, easier to implement/maintain and quite
possibly more efficient, then yes. If you prefer "interesting"* then
carry on as you were ;-)

* http://en.wikipedia.org/wiki/May_you_live_in_interesting_times
 
L

Lucas Kanebley Tavares

Lucas Kanebley Tavares schrieb:
I have a templatized class which has an attribute as: "T *data", all
constructors initialize it to zero, and then allocate memory for the
array (and that IS done correctly, I've checked).
What I find it strange, is that at one point I have to reallocate
the data, but if I put this in my operator= overload:
if (data != 0) delete data; //mem leak here
You don't need to check for 0, because deletion of a null-pointer is a
no-op.
data = new T[get_data_size()];
valgrind acuses a memory leak, [...]
Nevermind, sorry to bother you guys, after hours looking at it, I
stepped away for a minute and saw the missing brackets.. *sigh* Thank
you all, and sorry about the inconvenience.
You could use a std::vector<T> instead of a T*, so your class would
automatically be exception safe, copyable and assignable etc. without a
need to implement operator= and the copy constructor yourself.
Thanks for the tip, but it's actually an implementation of a "low-
diagonal" matrix, with a weird growth rate, so that wouldn't work. Well,
I guess it would... but still... =/

Are you aware that std::vector has a `resize()' member that will, if
necessary, do pretty much what your code does: delete and reallocate if
the vector has to grow? It probably also has a much cleverer memory
allocation scheme than you are likely to implement yourself.
Let me clarify. This is what the matrix is supposed to look like: 0
0 0
0 0 0
0 0 0 0
Only the value below the main diagonal are used. But it's not only that,
it could grow at a rate of 2 (or any number of) columns per row
(determined upon allocation), as such: 0
0 0 0
0 0 0 0 0
0 0 0 0 0 0 0
...
So, an implementation using vector would get boring FAST. heh

Boring?!? If boring == safer, easier to implement/maintain and quite
possibly more efficient, then yes. If you prefer "interesting"* then
carry on as you were ;-)

*http://en.wikipedia.org/wiki/May_you_live_in_interesting_times

LOL @ interesting life ;)

Yes, I'm familiar with resize(), I perhaps should've been clearer in
what I said.

What I meant from "boring" is that debugging STL is CRAP. I work with
it a lot when I need fast prototypes for things, or when I'm building
something that I believe won't cause me trouble. But the classes that
are to be "within" the matrix are the core of my program
(implementation and prototypes for several dynamic programming
algorithms for lot sizing problems) and I need to have a debugger
handy, which STL just can't deliver.

Thanks
Lucas Kanebley Tavares
 

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

Similar Threads

Does this constitute a memory leak? 8
memory leak 3
memory leak 4
Possible memory leak? 11
class template operator confusion 1
Memory leak problems 4
memory leak 26
Attempting to implement "weird" kind of graph 4

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top