memory allocation deallocation ...

P

pasa_1

Do you see anything wrong with using constructor 3 followed by a
function foo() as I have defined below?

class A {
member_variable_1;
ptr_member_variable_2;

public:
// Constructor 1
A():
member_variable_1(initial value),
ptr_member_variable_2(NULL) { };

// constructor 2
A(m_var_1, m_ptr_val_2):
member_variable_1(m_var_1),
ptr_member_variable_2(m_ptr_val_2) { };

// constructor 3
A(m_var_1)
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?
// Question1. do you see anything wrong in this approach?
};

~A()
{
if (!ptr_member_variable) {
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;
}
};

// foo uses only member_variable_1,
// doesn't care about the ptr member variable
foo();
};

Thanks in advance.
 
M

mlimber

pasa_1 said:
Do you see anything wrong with using constructor 3 followed by a
function foo() as I have defined below?

Please see the guidelines on posting code questions:

http://parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
class A {
member_variable_1;
ptr_member_variable_2;

For the sake of argument, let's give these types:

int member_variable_1;
int* ptr_member_variable_2;
public:
// Constructor 1
A():
member_variable_1(initial value),
ptr_member_variable_2(NULL) { };

// constructor 2
A(m_var_1, m_ptr_val_2):
member_variable_1(m_var_1),
ptr_member_variable_2(m_ptr_val_2) { };

// constructor 3
A(m_var_1)
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?
// Question1. do you see anything wrong in this approach?
};

The semicolons are extraneous after function definitions. Why don't you
combine these three (or at least the first two) into one:

A( int v = 0, int * p = 0 )
: member_variable_1(v)
, ptr_member_variable_2(p)
{}

The problem with the third constructor is that if you don't initialize
the pointer to 0 (or NULL), it may have *any* value whatsoever, and so
when you get to the destructor it will try to delete it if it is
non-zero, which is bad.

If you are passing in a pointer that this object takes ownership of
(i.e., the object is responsible for deleting it), I'd suggest using
std::auto_ptr in the parameter list to communicate this. Then you can
store it as a member in an auto_ptr, some other smart pointer, or even
a plain pointer, depending on your needs.
~A()
{
if (!ptr_member_variable) {
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;
}
};

You needn't check for NULL before deleting (see
http://parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.8). Also,
in general there is no need to set member pointers to NULL in the
destructor. The object is being destroyed, and so the variable becomes
inaccessible. BTW, if you use a smart pointer, this destructor will go
away altogether.
// foo uses only member_variable_1,
// doesn't care about the ptr member variable
foo();
};

Bottom line advice: Give everything an initial value.

Cheers! --M
 
V

VJ

pasa_1 said:
Do you see anything wrong with using constructor 3 followed by a
function foo() as I have defined below?

class A {
member_variable_1;
ptr_member_variable_2;

public:
// Constructor 1
A():
member_variable_1(initial value),
ptr_member_variable_2(NULL) { };

// constructor 2
A(m_var_1, m_ptr_val_2):
member_variable_1(m_var_1),
ptr_member_variable_2(m_ptr_val_2) { };

// constructor 3
A(m_var_1)
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?
// Question1. do you see anything wrong in this approach?
};

~A()
{
if (!ptr_member_variable) {
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;
}
};

// foo uses only member_variable_1,
// doesn't care about the ptr member variable
foo();
};

Thanks in advance.


yes, does not compile :p

also in the destructor you better compare ptr_member_variable to NULL.

in the constructor3, i hope you are doing:
ptr_member_variable=NULL
 
V

Victor Bazarov

pasa_1 said:
Do you see anything wrong with using constructor 3 followed by a
function foo() as I have defined below?

Yes. Your 'foo' doesn't have any return value type. And see my
comments inline.
class A {
member_variable_1;
ptr_member_variable_2;

Unless those are macros expanding into normal declarations, the
syntax is wrong: types are missing.
public:
// Constructor 1
A():
member_variable_1(initial value),
ptr_member_variable_2(NULL) { };

Trailing semicolons are extraneous. Drop'em.
// constructor 2
A(m_var_1, m_ptr_val_2):

Types are missing for the arguments.
member_variable_1(m_var_1),
ptr_member_variable_2(m_ptr_val_2) { };

// constructor 3
A(m_var_1)

Type is missing.
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?

The problem is that 'ptr_member_variable_2' has _undetermined_
value. Doing anything with it would have undefined behaviour.
// Question1. do you see anything wrong in this approach?
};

~A()
{
if (!ptr_member_variable) {

'ptr_member_variable' doesn't seem to exist. Did you fortet the
'_2'? And if you did, your c-tor 3 forgets to initialise that
variable, so bad things are bound to happen.
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;
}
};

// foo uses only member_variable_1,
// doesn't care about the ptr member variable
foo();
};

Thanks in advance.

V
 
D

Daniel T.

pasa_1 said:
// constructor 3
A(m_var_1)
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?
// Question1. do you see anything wrong in this approach?
};

You have to initialize the pointer to 0 (NULL) in order for it to work.
~A()
{
if (!ptr_member_variable) {
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;
}

Most of the above is unnecessary. Better would be:

~A()
{
delete ptr_member_variable_2;
}
 
D

David Harmon

in the constructor3, i hope you are doing:
ptr_member_variable=NULL

Rather, in the constructor initializer list,
: ptr_member_variable(0)

Initialization is generally preferable over uninitialized variables
to be assigned an initial value later... even one or two lines
later. Uninitialized pointers are the worst.
 
V

VJ

David said:
Rather, in the constructor initializer list,
: ptr_member_variable(0)

Initialization is generally preferable over uninitialized variables
to be assigned an initial value later... even one or two lines
later. Uninitialized pointers are the worst.

Yes, thank you.
But I would do:
: ptr_member_variable( NULL )
instead.
 
D

David Harmon

Yes, thank you.
But I would do:
: ptr_member_variable( NULL )
instead.

I wish I could agree with you, I really do. But, IMHO, the
standards committee screwed up the definition of NULL so badly that
you are better off avoiding it altogether. Most of the time it
makes no real difference, but when it does the difference is not in
favor of NULL.

Example
extern void foo(int);
extern void foo(void *);

Which one of those overloaded functions is surprisingly
invoked by foo(NULL) ?
 
V

Victor Bazarov

David said:
I wish I could agree with you, I really do. But, IMHO, the
standards committee screwed up the definition of NULL so badly that
you are better off avoiding it altogether. Most of the time it
makes no real difference, but when it does the difference is not in
favor of NULL.

Example
extern void foo(int);
extern void foo(void *);

Which one of those overloaded functions is surprisingly
invoked by foo(NULL) ?

Keeping it NULL will help when 'nullptr' keyword is instroduced
and becomes widespread; search-and-replace is so much easier and
precise with

NULL --> nullptr

than

0 --> nullptr

don't you think?

V
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Victor said:
Keeping it NULL will help when 'nullptr' keyword is instroduced
and becomes widespread; search-and-replace is so much easier and

Considering the fact that there are still in use many compilers that
implements poorly the actual standard, I suspect that the widespread
introduction of the next will be delayed until 2100.
 
D

David Harmon

On Fri, 27 Oct 2006 16:17:22 -0400 in comp.lang.c++, "Victor
Bazarov said:
Keeping it NULL will help when 'nullptr' keyword is instroduced
and becomes widespread; search-and-replace is so much easier and
precise with
NULL --> nullptr

Is that the way things are headed? I confess that I cannot keep up.
Well then, I suppose you have a reasonable point there. But I think
it is a sad thing to introduce a new keyword there, when making
((void *)0) a legitimate null pointer constant would seem to me the
obvious answer, without breaking any code that already uses the
identifier nullptr for any purpose. I suppose it is too much to
hope for that 0 would _stop_ being a legitimate null pointer?
I would gladly fix all the resulting compile errors in my code in
order to settle this once and for all.
 
V

Victor Bazarov

David said:
On Fri, 27 Oct 2006 16:17:22 -0400 in comp.lang.c++, "Victor


Is that the way things are headed? I confess that I cannot keep up.
Well then, I suppose you have a reasonable point there. But I think
it is a sad thing to introduce a new keyword there, when making
((void *)0) a legitimate null pointer constant would seem to me the
obvious answer,

It's not. How would you distinguish between that and simple void*
that is null? There is no easy way. And conversion from 'void*' to
any other pointer requires an explicit cast (and justifiedly so).
That is why 'nullptr' is being introduced; the compilers will be
able to perform proper pointer initialisation on the fly. Perhaps
you should read the n1601 document (see 2004 Committee papers).
without breaking any code that already uses the
identifier nullptr for any purpose. I suppose it is too much to
hope for that 0 would _stop_ being a legitimate null pointer?

It's not a legitimate null pointer. It never was. It is however
a legitimate integral [r]value that when converted to a pointer type
yields a null pointer. And it will remain such because otherwise
it would break too much existing code.
I would gladly fix all the resulting compile errors in my code in
order to settle this once and for all.

You will have that opportunity when 'nullptr' keyword is implemented.

V
 
G

Greg Comeau

I wish I could agree with you, I really do. But, IMHO, the
standards committee screwed up the definition of NULL so badly that
you are better off avoiding it altogether. Most of the time it
makes no real difference, but when it does the difference is not in
favor of NULL.

Example
extern void foo(int);
extern void foo(void *);

Which one of those overloaded functions is surprisingly
invoked by foo(NULL) ?

Well, but for at least the novice

foo(0);

probably yields something surprising too.

Of course though, NULL has a number of problems.
 
V

VJ

David said:
I wish I could agree with you, I really do. But, IMHO, the
standards committee screwed up the definition of NULL so badly that
you are better off avoiding it altogether. Most of the time it
makes no real difference, but when it does the difference is not in
favor of NULL.

Example
extern void foo(int);
extern void foo(void *);

Which one of those overloaded functions is surprisingly
invoked by foo(NULL) ?


#include <iostream>

void foo(int)
{
std::cout<<"int"<<std::endl;
}

void foo(void*)
{
std::cout<<"void*"<<std::endl;
}

int main()
{
int a = 0;
void *b = NULL;

foo(a);
foo(b);
foo(0);
foo(NULL);
}


In this example, my compiler made a warning:
f.cpp:21: warning: passing NULL to non-pointer argument 1 of 'void foo(int)'

But when you are going to pass NULL to a function?

I got next output:
int
void*
int
int

therefore I do not see why stop using NULL
 
V

VJ

VJ said:
But when you are going to pass NULL to a function?

Ok. Never mind this question. I know you can pass NULL, but if you
ignore warnings in your program, then we have different approach to
programming
 
P

Peter

pasa_1 said:
Do you see anything wrong with using constructor 3 followed by a
function foo() as I have defined below?

class A {
member_variable_1;
ptr_member_variable_2;

public:
// Constructor 1
A():
member_variable_1(initial value),
ptr_member_variable_2(NULL) { };

// constructor 2
A(m_var_1, m_ptr_val_2):
member_variable_1(m_var_1),
ptr_member_variable_2(m_ptr_val_2) { };

// constructor 3
A(m_var_1)
{
// do something with member_variable_1
// and don't bother about ptr_member_variable_2

// Since no memory was allocated for ptr_member_variable_2
// the d-ctor should not try to delete it?
// Question1. do you see anything wrong in this approach?
};

~A()
{
if (!ptr_member_variable) {
delete ptr_member_variable_2;
ptr_member_variable_2 = NULL;

this test is useless as it is safe to apply delete to a 0 pointer.
Setting the pointer to 0 after applying delete is more than useless,
as you can anyway not access it after the destructor has been called.
}
};

// foo uses only member_variable_1,
// doesn't care about the ptr member variable
foo();
};

Thanks in advance.


destroying something inside the destructor which has not been allocated
inside the constructor or any method of this class is bad style.
Also you may want to consider using std::auto_ptr<> for your pointer.
Don't allocate more than one resource inside a constructor but move
such allocations into member/base objects.
 
D

David Harmon

it is a sad thing to introduce a new keyword there, when making
((void *)0) a legitimate null pointer constant would seem to me the
obvious answer,

It's not. How would you distinguish between that and simple void*
that is null? [/QUOTE]

In my imagination, the generic null pointer constant would be spelled
((void *)0). It is distinguished from any other void pointer by being
written differently in the source, and by being a constant expression.
Just as currently, assigning 0 to a pointer is different than assigning
some int that happens to be 0.
And conversion from 'void*' to
any other pointer requires an explicit cast

Note that I did not say it should be a void* type. It would be a
special case, just as null pointer constants currently are. Since
conversion from a null pointer constant to any type of null pointer
value requires no cast, that part works.

I would also like to see ((T *)0) as a null pointer constant of the
specific pointer type, so that mismatches would be disallowed.
Perhaps you should read the n1601 document (see 2004 Committee papers).

Well, obviously I should.
I suppose it is too much to
hope for that 0 would _stop_ being a legitimate null pointer?

It's not a legitimate null pointer. It never was. It is however
a legitimate integral [r]value that when converted to a pointer type
yields a null pointer. And it will remain such because otherwise
it would break too much existing code.

It is "An integral constant expression rvalue of integer type that
evaluates to zero (called a null pointer constant)"

I don't know the proper standardese language for it, but I would like to
see that entirely replaced by something that makes ((void *)0) the magic
expression to use, along with #define NULL ((void*)0). Use of an
integer type there should have been left behind with C. Clearly, one
way or another, I'm not going to get what I want.
 

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,046
Latest member
Gavizuho

Latest Threads

Top