Question on delete [] vs just plain delete

D

DamonChong

Hi,

I am new to c++. I recently spend an enormous among of time
troubleshooting a seeminly innocuous piece of code. Although I narrow
down this piece of code as the culprit but I don't understand why. Can
some guru help to enlighten me? Thank you.

// I created an array of pointers to object pointers:

Object ** obs = new Object * [9];

// After that I populate this array:

for(int i=0; i<9; i++){
obs = new Object(i);
}

// After using them i deleted the array:

for(int i=0; i<9; i++){
delete obs;
}

delete [] obs;

delete obs; // this is the problem, during execution the program
hanged.

Apparently, the above caused undefined behaviour. But I don't know why
i shouldn't do that. Thanks again for any sharing!

Cheers,
Damon
 
E

Efrat Regev

DamonChong said:
Hi,

I am new to c++. I recently spend an enormous among of time
troubleshooting a seeminly innocuous piece of code. Although I narrow
down this piece of code as the culprit but I don't understand why. Can
some guru help to enlighten me? Thank you.

While the gurus answer more difficult questions, I'll field this one.
// I created an array of pointers to object pointers:

Object ** obs = new Object * [9];

/////////// Great, you've allocated an array of pointers to Object
// After that I populate this array:

for(int i=0; i<9; i++){
obs = new Object(i);


/////////// And now you've allocated the objects.
}

// After using them i deleted the array:

for(int i=0; i<9; i++){
delete obs;


/////////// Now you've deallocated the objects.
}

delete [] obs;

/////////// And now you've deallocated the array.


/////////// Good. So you've deallocated everything you've allocated. Nothing
left to deallocate.

/////////// and yet....
delete obs; // this is the problem, during execution the program
hanged.

/////////// So the previous line hangs since you're deallocating something
which you shouldn't
 
P

Peter Koch Larsen

Hi Damon

Efrat already answered your post, but I will recommend you do not use
new/delete as a newbie C++ programmer. Instead focus on the standard library
and just don't use pointers.
Pointers are difficult and better not used until you understand the basics
of C++ - including the standard library. By going this route, you will also
learn how little use there actually is of pointers in modern C++.

/Peter
 
A

ajk

delete [] obs;

delete obs; // this is the problem, during execution the program


normally you use delete [] on any array you allocate to tell the
compiler that the ptr you are deleting is an array.

it is just one of those not obvious c++ rules you need to learn :)

in any case I would suggest you use vector<> instead of array since it
is safer and more convenient. check up the online help/book for info.
STL in general can help you a lot.

/ajk
 
J

Jon

While I would agree that pointers are maybe not obvious for a beginner to
say that there is "little use" of pointers in modern c++ is just plain wrong
in my opinion. Of course it maybe depends on what you define as "modern c++"
but that is another question...

Peter Koch Larsen said:
Hi Damon

Efrat already answered your post, but I will recommend you do not use
new/delete as a newbie C++ programmer. Instead focus on the standard
library and just don't use pointers.
Pointers are difficult and better not used until you understand the basics
of C++ - including the standard library. By going this route, you will
also learn how little use there actually is of pointers in modern C++.

/Peter
DamonChong said:
Hi,

I am new to c++. I recently spend an enormous among of time
troubleshooting a seeminly innocuous piece of code. Although I narrow
down this piece of code as the culprit but I don't understand why. Can
some guru help to enlighten me? Thank you.

// I created an array of pointers to object pointers:

Object ** obs = new Object * [9];

// After that I populate this array:

for(int i=0; i<9; i++){
obs = new Object(i);
}

// After using them i deleted the array:

for(int i=0; i<9; i++){
delete obs;
}

delete [] obs;

delete obs; // this is the problem, during execution the program
hanged.

Apparently, the above caused undefined behaviour. But I don't know why
i shouldn't do that. Thanks again for any sharing!

Cheers,
Damon

 
E

Efrat Regev

DamonChong said:
Thanks alot. Kind of silly I suppose to make such mistake. ;P

No problem. BTW, explicit memory management is both very powerful, and
very prone to making "silly" mistakes (which I don't think are silly at
all). Consequently, perhaps you might want to read Peter Koch Larsen's
response (with which I completely agree).

Specifically, you could write your code this way:

#include <vector>

std::vector<Object> obs[9];

for(int i = 0; i < 9; ++i)
obs = Object(i);

Or if Object doesn't have a default constructor,

#include <vector>
#include <boost/shared_ptr.hpp>

std::vector<boost::shared_ptr<Object> > obs(9);

for(int i = 0; i < 9; ++i)
obs.reset(new Object(i));

(You could google for boost smart_ptr for the above).
 
B

Bradley

My question is why dynamically allocate an array of Object pointers. Why not
just just

Object *obparray[9];

??

Is memory that sparse now days?
 
E

Efrat Regev

Bradley said:
My question is why dynamically allocate an array of Object pointers. Why not
just just

Object *obparray[9];

??

Is memory that sparse now days?

It's possible that Object doesn't have a default constructor.
 
E

Efrat Regev

Efrat Regev said:
Bradley said:
My question is why dynamically allocate an array of Object pointers. Why not
just just

Object *obparray[9];

??

Is memory that sparse now days?

It's possible that Object doesn't have a default constructor.

Oops! my bad - I misunderstood your post.
 
O

Old Wolf

Efrat said:
Specifically, you could write your code this way:

#include <vector>

std::vector<Object> obs[9];

for(int i = 0; i < 9; ++i)
obs = Object(i);

Or if Object doesn't have a default constructor,

#include <vector>
#include <boost/shared_ptr.hpp>

std::vector<boost::shared_ptr<Object> > obs(9);

for(int i = 0; i < 9; ++i)
obs.reset(new Object(i));

(You could google for boost smart_ptr for the above).


You don't need to go to those lengths; this would do,
if Object is copyable:

.. std::vector<Object> obs;
.. for(int i = 0; i != 9; ++i)
.. obs.push_back( Object(i) );
 
M

msalters

Efrat said:
Specifically, you could write your code this way:

#include <vector>

std::vector<Object> obs[9];

for(int i = 0; i < 9; ++i)
obs = Object(i);


Actually, you mean
std::vector<Object> obs(9);

which is one vector with initially 9 elements, and not
9 vectors with initially no elements.

With your [9] declaration, the compiler will complain that it
can't assign Object(0) to an empty vector of Objects.

You could also be a bit clearer, and write the size only once:

#include <vector>

std::vector<Object> obs; // empty

for(int i = 0; i < 9; ++i)
obs.pushback( Object(i) ); // add one element at a time.

Now, there's only one occurence of 9 - if the vector should ever
change size, you can do so in one place.

HTH,
Michiel Salters
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top