Question about delete

J

John

Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

Thanks.

john
 
R

Rob Williscroft

John wrote in in
comp.lang.c++:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena",

delete [] arena;
that memory will be released, right?
Is ptr an dangling pointer now?

Yes and so is arena.

Rob.
 
R

Ron Natalie

John said:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

If you say delete area, you have undefined behavior. It needs
to be delete[] arena.

Yes ptr is dangling after that. In addition, you may also lose
any resorces allocated in the Image class since it never gets
destructed.


Imagine:
class Image {
std::string name;
char pixels[100000];
};

Your above code snippet will leak resources that std::string allocates
internally.
 
V

Victor Bazarov

Ron said:
John said:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

If you say delete area, you have undefined behavior. It needs
to be delete[] arena.

Yes ptr is dangling after that. In addition, you may also lose
any resorces allocated in the Image class since it never gets
destructed.


Imagine:
class Image {
std::string name;
char pixels[100000];

public:
Image(const std::string& n) : name(n) {}
};

Your above code snippet will leak resources that std::string allocates
internally.

....and to fight that you need to explicitly call the Image's d-tor:

ptr->~Image();

before attempting to free the memory.

Just my $0.02...

V
 
D

David Lindauer

John said:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

you only need to delete it once, but also choose what you delete
carefully. if you delete 'arena' no destructor will be called, but if
you delete 'ptr' the destructor will be called if there is one. (your
second statement has the side effect of calling a constructor if there
is one) I don't think delete ever nulls pointers though, so in a sense
both pointers are dangling after the delete. however, if you did two
news on the same memory address and both were objects with constructors,
you could cause yourself problems depending on what those constructors
do.

David
 
P

Peter Koch Larsen

David Lindauer said:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

you only need to delete it once, but also choose what you delete
carefully. if you delete 'arena' no destructor will be called, but if
you delete 'ptr' the destructor will be called if there is one. (your
second statement has the side effect of calling a constructor if there
is one) I don't think delete ever nulls pointers though, so in a sense
both pointers are dangling after the delete. however, if you did two
news on the same memory address and both were objects with constructors,
you could cause yourself problems depending on what those constructors
do.

David
delete ptr will cause undefined behaviour. What is needed is ptr->~ptr() to
call the destructor of Image and delete[] arene to release memory.

/Peter
 
J

John

Ron Natalie said:
John said:
Hi:

I have a question from the book---C++ primer, page 677.

char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

After the above two lines, arena and ptr point to the same memory.
If I "delete arena", that memory will be released, right?
Is ptr an dangling pointer now?

If you say delete area, you have undefined behavior. It needs
to be delete[] arena.

Yes ptr is dangling after that. In addition, you may also lose
any resorces allocated in the Image class since it never gets
destructed.


Imagine:
class Image {
std::string name;
char pixels[100000];
};

Sorry, I can not understand. Is "size of Image" = size of name + 10000?
Is the size of memory that arena points to = size of name + 10000?
Your above code snippet will leak resources that std::string allocates
internally.

Why?
 
R

Ron Natalie

David said:
you only need to delete it once, but also choose what you delete
carefully. if you delete 'arena' no destructor will be called, but if
you delete 'ptr' the destructor will be called if there is one.

However, calling delete on ptr will pass the memory back the wrong
allocation function. Objects don't have memory as to how they were
allocated, the context of the delete expression has to figure it out
(and does it wrong in this case).

As Victor pointed out, if you are going to create an object with
placement new, you'll have to make an explicit call to the destructor
prior to deallocating the storage.
 
R

Ron Natalie

John said:
Imagine:
class Image {
std::string name;
char pixels[100000];
};


Sorry, I can not understand. Is "size of Image" = size of name + 10000?
Is the size of memory that arena points to = size of name + 10000?

More or less. There might be some padding in there as well (although in
this case it would be unlikely).

Because std::string's member functions themselves allocate memory OUTSIDE
the class. Imagine this case instead.

classs SillyString {
char* ptr;
public:
SillyString() { ptr = new char[100]; }
~SillyString() { delete [] ptr; }
// need copy constructor and copy assignment operator too...
};
class Image {
public:
SillyString name;
char pixels[10000];
};

Now if we construct an Image object, SillyString allocates memory.
It can only get deallocated if somehow the destructor for Image is
invoked (which will in turn cause the destructor for SillyString\
to be called).
 
D

David Lindauer

Ron said:
However, calling delete on ptr will pass the memory back the wrong
allocation function. Objects don't have memory as to how they were
allocated, the context of the delete expression has to figure it out
(and does it wrong in this case).

As Victor pointed out, if you are going to create an object with
placement new, you'll have to make an explicit call to the destructor
prior to deallocating the storage.

thanks for the heads up!
 
J

John

Ron Natalie said:
John said:
Imagine:
class Image {
std::string name;
char pixels[100000];
};


Sorry, I can not understand. Is "size of Image" = size of name + 10000?
Is the size of memory that arena points to = size of name + 10000?

More or less. There might be some padding in there as well (although in
this case it would be unlikely).

Because std::string's member functions themselves allocate memory OUTSIDE
the class. Imagine this case instead.

classs SillyString {
char* ptr;
public:
SillyString() { ptr = new char[100]; }
~SillyString() { delete [] ptr; }
// need copy constructor and copy assignment operator too...
};
class Image {
public:
SillyString name;
char pixels[10000];
};

Now if we construct an Image object, SillyString allocates memory.
It can only get deallocated if somehow the destructor for Image is
invoked (which will in turn cause the destructor for SillyString\
to be called).

Yes. I agree.
But in my original post as below:
char *arena = new char[ sizeof Image ];
Image *ptr = new (arena) Image( "Quasimodo" );

arena and ptr point to the same memory. If I "delete [] arena", that
part of memory is deallocated. Certainly, ptr is a dangling pointer
now. But the memory that ptr points to is deallocated. So if "size of
Image" = size of name + 10000, the memory that the string "name"
occupied is also deallocated. Am I right? So the question is: is the
string "name" a part of image?

John
 

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
474,183
Messages
2,570,970
Members
47,527
Latest member
RoxanneTos

Latest Threads

Top