473,405 Members | 2,445 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Why can you delete a const pointer?

I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();

Please, enlighten me!

Dec 28 '05 #1
21 18514
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.

template <class T>
void f()
{
// make sure the T never changes
const T* t = new T;

// huh.. what do I do here to delete t?
}
Jonathan

Dec 28 '05 #2
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?

Dec 28 '05 #3
Roman Werpachowski wrote:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


No, except by using a smart pointer or a handle.

If you absolutely need a raw pointer, you could define an operator
delete() in the class and make it private. This would catch a "delete
p;" but would make it impossible to create objects directly (new T).
Note that both these restrictions could be foiled by using the global
operators.

Why give the pointer in the first place anyways? People will be much
less tempted to delete the object if you give a reference.

Jonathan

Dec 28 '05 #4

Roman Werpachowski escreveu:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


If you return a reference to the pointed to object, the user of your
class can't delete it because you can't delete a reference.

const T & A::f() const
{
return *t;
}

HTH,

Marcelo Pinto.

Dec 28 '05 #5
Marcelo Pinto wrote:
Roman Werpachowski escreveu:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


If you return a reference to the pointed to object, the user of your
class can't delete it because you can't delete a reference.

const T & A::f() const
{
return *t;
}


Perhaps, but you can delete the object at its address:

void f(A& a)
{
T& t(a.f());
delete &t;
}

But as I said, users will be much less tempted to do that, compared to
returning by address.
Jonathan

Dec 28 '05 #6

"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).

There are two things going on in the OP's code that affect its "legality".

First, it's an initialization, which is legal for const pointers.

Second, he does not have constant pointers at all! That code shows a
pointer to const double, _not_ a const pointer to double. It's perfectly
legal to assign to a pointer-to-const. It's what it's pointing to that's
constant.

Consider:

double * x = new double;
const double * p = NULL; // legal - just an initialization
p = x; // still ok, since p is not a const pointer (but rather a
pointer-to-const)
*p = 1.2; // oops! illegal = assigning to const double

const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer
-Howard


Dec 28 '05 #7

"Howard" <al*****@hotmail.com> wrote in message
news:_W*********************@bgtnsc04-news.ops.worldnet.att.net...

"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();
Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).

There are two things going on in the OP's code that affect its "legality".

First, it's an initialization, which is legal for const pointers.

Second, he does not have constant pointers at all! That code shows a
pointer to const double, _not_ a const pointer to double. It's perfectly
legal to assign to a pointer-to-const. It's what it's pointing to that's
constant.

Consider:

double * x = new double;
const double * p = NULL; // legal - just an initialization
p = x; // still ok, since p is not a const pointer (but rather a
pointer-to-const)
*p = 1.2; // oops! illegal = assigning to const double

const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


(BTW, I meant that to be p1 = x1;)


Forgot to show this one (the allocation of a const pointer):

double * const p2 = NULL; // legal - just an initialization
p2 = new double; // oops! illegal - assigning to const pointer

The allocation of p2 would be fine as an initialization, but not as an
assignment, because it's const.

-Howard


Dec 28 '05 #8
Howard wrote:
"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).


By "allocation", I meant initialization by a newly allocated object,
not changing a pointer value (which was not the point).
Jonathan

Dec 28 '05 #9
Howard napisal(a):
const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


Is

delete p1;

legal or not?

Dec 28 '05 #10
Jonathan Mcdougall napisal(a):
Why give the pointer in the first place anyways? People will be much
less tempted to delete the object if you give a reference.


I wanted to use references first, but got bogged down on such code:

class pipek {
};

class klasa {
private:
pipek& p_;
public:
void set_p(pipek& p)
{
p_ = p;
}
};

class mazut {
private:
pipek p_;
public:
pipek& get_p()
{
return p_;
}
};

int main()
{
klasa k1;
mazut m1;

k1.set_p( m1.get_p() );
}

it compiles with error:

test.cc: In function `int main()':
test.cc:25: error: structure `k1' with uninitialized reference members

while assigning a pointer to a pointer works just fine.

Dec 28 '05 #11
On Wed, 28 Dec 2005 13:30:23 -0800, Roman Werpachowski wrote:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


Make the destructor private, accessible only by a member function or
friends of the class.

- Jay
Dec 28 '05 #12
Roman Werpachowski wrote:
I wanted to use references first, but got bogged down on such code:

class pipek {
};

class klasa {
private:
pipek& p_;
public:
void set_p(pipek& p)
{
p_ = p;
}
};

class mazut {
private:
pipek p_;
public:
pipek& get_p()
{
return p_;
}
};

int main()
{
klasa k1;
mazut m1;

k1.set_p( m1.get_p() );
}

it compiles with error:

test.cc: In function `int main()':
test.cc:25: error: structure `k1' with uninitialized reference members

while assigning a pointer to a pointer works just fine.


I think you missed something about references.
Reference is an alternate name for existing object (a synonim).
So, what should become clear now, reference must always refer to
existing object.

The problem is that in your class klasa default constructor does not
initializes reference. So, you have to provide initializetion
explicitely passing existing object of class of pipek as a constructor
parameter.

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #13
So I should store the pointer internally and use references in the
interface?

Dec 28 '05 #14
Roman Werpachowski wrote:
So I should store the pointer internally and use references in the
interface?


Hm, it depends on your requirements and assumptions.
You can have member as value or as pointer:

class A
{
myclass data; // data is initialized by default constructor of myclass
}

class B
{
myclass* pdata; // here you pointer
public:
B() : pdata(0) {} // pdata is nullpointer by default
}

In class A you always play with instance of myclass,
because the lifetime of data is determined by lifetime of instance of A.

In class B situation is different. pdata may or may not point to any
instance of myclass during whole lifetime of A.

Now, you have to be aware that client of object of B may get nullpointer
as a result of query for pdata (e.g. using accessor myclass* getData()
const;) or may get pointer pointing to existing instance of myclass.
Here it comes more complex than when working with class A.

Simply, you have to thing about the ownership issues and if you want to
allow ownership transfer or not, etc.

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #15
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?

Dec 28 '05 #16
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?

Thanks for your patience, folks ;-)

Dec 28 '05 #17
Roman Werpachowski wrote:
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?


Yes, it is.
Plugin will be loaded/unloaded so it's lifetime is not staticaly set up.
Cheers

--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #18

"Roman Werpachowski" <ro****************@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Howard napisal(a):
const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


Is

delete p1;

legal or not?


Yes, it's legal. You have to be able to delete, even const pointers, or
else you'd have a leak every time you initialize one via new.

-Howard
Dec 28 '05 #19
Your answers cleared up the confusion in my head. Thanks!

Dec 29 '05 #20
Roman Werpachowski wrote:
Your answers cleared up the confusion in my head. Thanks!


For me too. I was a bit surprised about such obvious issue as memory
leaks. From time to time I'm surprised how obvious things can hide
and seem so unobvious :-)

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 29 '05 #21
you got a mistake, p is not a const pointer, *p is a const double
just-so-so

Dec 29 '05 #22

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: foo | last post by:
I'm creating a debug class called debug_mem_allocation for the purpose of finding memory leaks. I used macro's to replace the new and delete operators. My problem is with trying to replace the...
16
by: cppaddict | last post by:
Hi, I am deleting some objects created by new in my class destructor, and it is causing my application to error at runtime. The code below compiles ok, and also runs fine if I remove the body...
5
by: Sid | last post by:
Hi, I was going through this reference code and playing around with it. The code (shown below) shows a class that represents a stack of string pointers In the code below in particular in the...
6
by: R.Z. | last post by:
i'm using a class from some api that is said to automatically call its destructor when its out of scope and deallocate memory. i create instances of this class using "new" operator. do i have to...
13
by: gary | last post by:
Hi, We all know the below codes are dangerous: { int *p = new int; delete p; delete p; } And we also know the compilers do not delete p if p==NULL. So why compilers do not "p = NULL"...
19
by: Xavier Dcoret | last post by:
Hi, I long thought one could not delete a const pointer but the following code compiles under g++ and visual net: class Dummy { public: Dummy() {} ~Dummy() {}
6
by: valerij | last post by:
Please help. I have been on this problem for a week now. I am using Windows 98SE, Microsoft Visual C++ 6.0 The following program only works when the function is not called, BUT the function does...
10
by: =?iso-8859-1?q?Ernesto_Basc=F3n?= | last post by:
I am implementing my custom smart pointer: template <typename T> class MySmartPtr { public: MySmartPtr(T* aPointer) { mPointer = aPointer; }
19
by: Daniel Pitts | last post by:
I have std::vector<Base *bases; I'd like to do something like: std::for_each(bases.begin(), bases.end(), operator delete); Is it possible without writing an adapter? Is there a better way? Is...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.