a deconstructor question

X

Xiaoshen Li

Dear All,

I am a little confused.

//Objects of this class are partially filled arrays of doubles
class PFArray
{
public:
...
~PFArray();
private:
double *a; //for an array of doubles
..
};

PFArray::~PFArray()
{
delete [] a;
}

The code "double *a" in the private section of class PFArray doesn't
NECESSARILY tell that a is a pointer to an array (it coulde be a pointer
to a double, right?). Why the deconstructor use " delete [] a "? If a
instead is pointer to a double, then "delete a" should be used?
 
X

Xiaoshen Li

Thank you for the help. But I am not sure you are right.
I took C++ class three years ago. Since then, I didn't use it.
Yesterday, I saw the code in the class passed by the professor:

class Person
{
public:
..
~Person();
private:
char *name;
};

Person::~Person()
{
delete [] name;
}

Since name could be pointing a single char or a char array, why the
destructor uses "delete [] name"?

Thank you again.
 
X

Xiaoshen Li

Thank you very much, Mike.

#include <string>
using namespace std;

class Person
{
publice:
...
private:
string name;
int age;
char gender;
}

With above class, is destructor needed or not? My guess is not, am I
correct?
 
X

Xiaoshen Li

Could you kindly elaborate why "don't import std, instead use
std::string"? Thank you very much.
 
M

Mike Wahler

Xiaoshen Li said:
Dear All,

I am a little confused.

//Objects of this class are partially filled arrays of doubles
class PFArray
{
public:
...
~PFArray();
private:
double *a; //for an array of doubles
..
};

PFArray::~PFArray()
{
delete [] a;
}

The code "double *a" in the private section of class PFArray doesn't
NECESSARILY tell that a is a pointer to an array (it coulde be a pointer
to a double, right?).

It *is* a pointer to type double. A pointer to an array would look like
e.g:

double (*a)[size];
Why the deconstructor use " delete [] a "?

It should only use 'delete[]' if the value of the pointer
'a' was returned 'new[]' or is NULL (0).
Otherwise the behavior is undefined.
If a instead is pointer to a double, then "delete a" should be used?

Only if 'a's value was returned by 'new' (not '[]').

a = new double; // allocates a single type double object
delete a; // deallocate the single type double object
// delete[] a; // undefined behavior.

a = new double[5]; // allocates array of five type double objects
delete[] a; // deallocate the array of five doubles//
delete a; // undefined behavior.

double d;
a = &d; // 'a's value not from 'new' or 'new[]'
delete d; // undefined behavior
delete[] d; // undefined behavior

Which C++ book(s) are you reading?

-Mike
 
J

Jacek Dziedzic

Xiaoshen said:
Thank you for the help. But I am not sure you are right.

He is.
I took C++ class three years ago. Since then, I didn't use it.
Yesterday, I saw the code in the class passed by the professor:

class Person
{
public:
..
~Person();
private:
char *name;
};

Person::~Person()
{
delete [] name;
}

Since name could be pointing a single char or a char array, why the
destructor uses "delete [] name"?

The rule is -- if you allocate with new[], you deallocate
with delete[]. If you allocate with new, you deallocate with
delete.

Therefore the code by "the professor" is fine only if storage
for 'name' is allocated with new[] (which is most probably
the case).

HTH,
- J.
 
M

Mike Wahler

Xiaoshen Li said:
Thank you for the help. But I am not sure you are right.

Why not? What specifically did I state that you
believe is not correct.
I took C++ class three years ago. Since then, I didn't use it. Yesterday,
I saw the code in the class passed by the professor:

class Person
{
public:
..

What's the code you left out?
~Person();
private:
char *name;
};

Person::~Person()
{
delete [] name;
}

Since name could be pointing a single char or a char array, why the
destructor uses "delete [] name"?

Because it's assuming that 'name' was given a value by
'new[]' (not 'new', nor the address operator). If this
assumption proves false, the code is broken.

Anyway, you should not be using 'C-style' strings,
use a std::string object instead, then all the issues of
allocation/deallocation disappear (the std:: string objects
handle their own memory management for you automatically).

#include <string>

class Person
{
std::string name;
}; // no need for 'new' or 'delete'

-Mike
 
P

Paul Henderson

Nope, no destructor needed there, as name will delete its own buffer.
But don't import std...use std::string!
 
P

Paul Henderson

Oh, just better practice in many people's opinion [though I might start
an argument if I say that too strongly]. Basically, there's no point in
*having* the std namespace if you're just going to include it at global
scope everywhere, and there's a danger of symbol-name conflicts between
your code and bits of std. But it doesn't really matter :)
 
G

Gavin Deane

Paul Henderson wrote:

Oh, just better practice in many people's opinion [though I might start
an argument if I say that too strongly]. Basically, there's no point in
*having* the std namespace if you're just going to include it at global
scope everywhere, and there's a danger of symbol-name conflicts between
your code and bits of std. But it doesn't really matter :)

Please quote some context in your message.

It is true that if you put a using directive or using declaration in
your own source file, it only affects you. As long as you understand
the issue, it's up to you whether you do it. However, the code that
sparked this discussion was a class definition, which could well reside
in a header file. If so, the argument for explicitly qualifying names
from the std namespace in preference to a using directive or
declaration should be made much more strongly.

If you put using namespace std or even using std::string in a header
file, *everyone* who includes your header file gets the namespace
pollution, whether they want it or not. This is very different from you
deciding to accept namespace pollution contained within your own source
file.

So it might be fair to say "But it doesn't really matter" if you are
talking about a source file, particularly in a toy program you are
writing for practice. But in a header file it really does matter. Don't
put using directives or using declarations in header files.

Gavin Deane
 
G

Guest

Xiaoshen said:
Dear All,

I am a little confused.

//Objects of this class are partially filled arrays of doubles
class PFArray
{
public:
...
~PFArray();
private:
double *a; //for an array of doubles
..
};

PFArray::~PFArray()
{
delete [] a;
}


Put raw arrays away.
Use std::vector for elements of type of double.

Cheers
 
G

Guest

Xiaoshen said:
Thank you for the help. But I am not sure you are right.
I took C++ class three years ago. Since then, I didn't use it.

Do you mean you didn't use delete[] ?
Look here:
http://www.softsurfer.com/Archive/algorithm_0205/#poly_simplify()

Point* vt = new Point[n]; // vertex buffer
int* mk = new int[n] = {0}; // marker buffer
// ...
delete vt;
delete mk;

There are still big amount of old code with this buggy way of destroying
arrays: delete instead of delete[]
Since name could be pointing a single char or a char array, why the
destructor uses "delete [] name"?

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13

Cheers
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top