473,748 Members | 2,887 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Preventing delete

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() {}
};

int main(int,char** )
{
const Dummy* const p = new Dummy();
delete p;

return 0;
}
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?

#include <iostream>
#include <string.h>

using namespace std;

class Invoice
{
public:
Invoice(char* label)
{
_label = strdup(label);
}
~Invoice()
{
delete [] _label;
}
const char* const label() const
{
return _label;
}
private:
char* _label;
};

int main(int,char** )
{
Invoice d("train");
delete [] d.label();

cout<<d.label() <<endl;

return 0;
}
Jan 31 '06 #1
19 2605
Xavier Décoret wrote:
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?


Make the destructor private or protected, and make the user call a
custom function that you supply to do the deleting.

Jan 31 '06 #2

Xavier Décoret wrote:
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() {}
};

int main(int,char** )
{
const Dummy* const p = new Dummy();
delete p;

return 0;
}
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?

#include <iostream>
#include <string.h>

using namespace std;

class Invoice
{
public:
Invoice(char* label)
{
_label = strdup(label);
}
~Invoice()
{
delete [] _label;
}
const char* const label() const
{
return _label;
}
private:
char* _label;
};

int main(int,char** )
{
Invoice d("train");
delete [] d.label();

cout<<d.label() <<endl;

return 0;
}


Are you asking purely out of academic interest? Because the real world
answer to that particular code is, for the class designer: "don't
expose the internals of your class like that" and for the client code:
"don't delete memory you don't own".

In other words, can you provide a more realistic example of the problem
you are trying to solve.

Gavin Deane

Jan 31 '06 #3
Xavier Décoret wrote:
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() {}
};

int main(int,char** )
{
const Dummy* const p = new Dummy();
delete p;

return 0;
}
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?


Create your own type and override operator delete?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Jan 31 '06 #4

Pete C wrote:
Xavier Décoret wrote:
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?


Make the destructor private or protected, and make the user call a
custom function that you supply to do the deleting.


That works for your own types. The OP's code was deleting a pointer to
char. I don't know of anything you can do to a pointer to a built in
type that prevents it being deleted (apart from wrapping it in a
class).

Gavin Deane

Jan 31 '06 #5
>
Are you asking purely out of academic interest? Because the real world
answer to that particular code is, for the class designer: "don't
expose the internals of your class like that" and for the client code:
"don't delete memory you don't own".

I don't buy this argument: encapsulation is meant to prevent tthe API
user to shoot himself in the foot. If you expect the programmer to be
intelligent, you do not need the const qualifier. Just trust the
programmer not to modify an object he is not allowed to ;-). And you do
not need smart pointers. Just trust the programmer to delete cleanly
every chunk of memory. And so on...

Regarding exposure of internal data, this happens all the time! Or your
class is generally useless. If you want a less academic example, just try:

#include <string>
#include <iostream>

using namespace std;

int main()
{
string s("foobar");

cout<<s<<endl;

delete [] s.c_str();

cout<<s<<endl;

return 0;
}

You cannot not do simpler. It is using a standard class (which is
developped by valuable people according to Scott Meyers ;-)). The class
must return pointer to raw data. Yet I can delete it and the above
program dumps in an unpleasant manner.

foobar
*** glibc detected *** ./a.out: free(): invalid pointer: 0x087041e4 ***
======= Backtrace: =========
/lib/libc.so.6[0x3fe124]
/lib/libc.so.6(__lib c_free+0x77)[0x3fe65f]
/usr/lib/libstdc++.so.6( _ZdlPv+0x21)[0x66b0a9]
/usr/lib/libstdc++.so.6( _ZdaPv+0x1d)[0x66b0f5]
../a.out(__gxx_per sonality_v0+0x1 a9)[0x8048909]
/lib/libc.so.6(__lib c_start_main+0x df)[0x3afd5f]
../a.out(__gxx_per sonality_v0+0x6 1)[0x80487c1]
======= Memory map: ========
0022d000-00247000 r-xp 00000000 08:01 655395 /lib/ld-2.3.5.so
00247000-00248000 r--p 00019000 08:01 655395 /lib/ld-2.3.5.so
00248000-00249000 rw-p 0001a000 08:01 655395 /lib/ld-2.3.5.so
0024d000-0024e000 r-xp 0024d000 00:00 0 [vdso]
00376000-00399000 r-xp 00000000 08:01 659189 /lib/libm-2.3.5.so
00399000-0039a000 r--p 00022000 08:01 659189 /lib/libm-2.3.5.so
0039a000-0039b000 rw-p 00023000 08:01 659189 /lib/libm-2.3.5.so
0039b000-004be000 r-xp 00000000 08:01 655494 /lib/libc-2.3.5.so
004be000-004c0000 r--p 00123000 08:01 655494 /lib/libc-2.3.5.so
004c0000-004c2000 rw-p 00125000 08:01 655494 /lib/libc-2.3.5.so
004c2000-004c4000 rw-p 004c2000 00:00 0
005a0000-005a9000 r-xp 00000000 08:01 659349
/lib/libgcc_s-4.0.2-20051126.so.1
005a9000-005aa000 rw-p 00009000 08:01 659349
/lib/libgcc_s-4.0.2-20051126.so.1
005c1000-00696000 r-xp 00000000 08:01 1717334 /usr/lib/libstdc++.so.6. 0.7
00696000-0069b000 rw-p 000d5000 08:01 1717334 /usr/lib/libstdc++.so.6. 0.7
0069b000-006a0000 rw-p 0069b000 00:00 0
08048000-08049000 r-xp 00000000 00:12 1945771
/home/artis/decoret/tmp/a.out
08049000-0804a000 rw-p 00000000 00:12 1945771
/home/artis/decoret/tmp/a.out
08704000-08725000 rw-p 08704000 00:00 0 [heap]
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7f2a000-b7f2c000 rw-p b7f2a000 00:00 0
b7f45000-b7f47000 rw-p b7f45000 00:00 0
bf931000-bf947000 rw-p bf931000 00:00 0 [stack]
Abort

In other words, can you provide a more realistic example of the problem
you are trying to solve.

Gavin Deane

Jan 31 '06 #6
Gavin Deane wrote:
Pete C wrote:
Xavier Décoret wrote:
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?


Make the destructor private or protected, and make the user call a
custom function that you supply to do the deleting.

That works for your own types. The OP's code was deleting a pointer to
char. I don't know of anything you can do to a pointer to a built in
type that prevents it being deleted (apart from wrapping it in a
class).

Gavin Deane


Yep. The Invoice dummy example is also deleting a const pointer on a
custom type, so it is not a problem of builtin types.
Jan 31 '06 #7
Xavier Décoret wrote:
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() {}
};

int main(int,char** )
{
const Dummy* const p = new Dummy();
delete p;

return 0;
}
The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?

BTW, this seems a recurring question:

http://www.codecomments.com/C_Modura...e719344-1.html

The important point is "how to control what the users do with pointer".
The const qualifier prevents him to modify it but not to delete it.
Jan 31 '06 #8
Xavier Décoret wrote:
Hi,

I long thought one could not delete a const pointer but the following
code compiles under g++ and visual net:
Sure you can. You can't assign a new value, or null, but delete doesn't
actually change the pointer value. (Or do you mean a pointer-to-const,
which is another beast?)
class Dummy
{
public:
Dummy() {}
~Dummy() {}
};

int main(int,char** )
{
const Dummy* const p = new Dummy();
delete p;
}
Const pointer to const Dummy, but obviously you can delete it.
p doesn't change, nor does *p. The end of a lifetime doesn't count
as a change, just like the beginning doesn't. There are no const
ctors or dtors, either.

The question is: how can I forbid the user to delete some data I an
handling a pointer to? Here is an example of code that does compile but
will lead to segfault. How can I prevent it?
You can't. The user can always do stupid things like 'delete new
Dummy[2];'
Point is, the users we're talking about are programmers. They're smart
enough to read the manual, at least in theory.
#include <iostream>
#include <string.h>

using namespace std;

class Invoice
{
public:
Invoice(char* label)
{
_label = strdup(label);
}
~Invoice()
{
delete [] _label;
}
const char* const label() const
{
return _label;
}
private:
char* _label;
};
Whoa. Programmers are supposed to read the manual, remember?
That includes you. strdup isn't standard C++. All implementations
I know require you to use free(). I bet yours does as well. However,
I don't suggest you change that. Read on instead.
int main(int,char** )
{
Invoice d("train");
delete [] d.label();

cout<<d.label() <<endl;

return 0;
}


That should trigger a warning or two. Invoice::Invoic e takes a
non-const char*
but "train" is definitely a const literal.

The solution is of course very simple: don't mix C and C++ like you do.
Drop
<string.h> and use <string>. Invoice::Invoic e should take a std::string
const&.
label() should return a string const&. The data member should be a
std::string.
Drop all strdup()s, free()s, delete[]s and just assign strings like
they're ints.

As a bonus, performance may even increase.

HTH,
Michiel Salters

Jan 31 '06 #9

Xavier Décoret wrote:

Are you asking purely out of academic interest? Because the real world
answer to that particular code is, for the class designer: "don't
expose the internals of your class like that" and for the client code:
"don't delete memory you don't own".

I don't buy this argument: encapsulation is meant to prevent tthe API
user to shoot himself in the foot. If you expect the programmer to be
intelligent, you do not need the const qualifier. Just trust the
programmer not to modify an object he is not allowed to ;-).


There's a difference between shooting yourself in the foot by accident
because your gun (API) doesn't have a safety catch (const) and shooting
yourself in the face because you have no idea how a gun works or what
you can do with it (are prone to passing things to delete just because
they are pointers to dynamically allocated memory).
And you do
not need smart pointers. Just trust the programmer to delete cleanly
every chunk of memory. And so on...
But the code to manage that memory in an exception safe manner is more
complicated without smart pointers. A competent C++ programmer could
still write it but it would take longer, be harder to read and be
harder to modify correctly. That's what smart pointers are for.
Regarding exposure of internal data, this happens all the time! Or your
class is generally useless. If you want a less academic example, just try:
OK, fair enough.
#include <string>
#include <iostream>

using namespace std;

int main()
{
string s("foobar");

cout<<s<<endl;

delete [] s.c_str();
That's still an academic example because no C++ programmer who knows
anything about C++ programming would ever do that. If you've got
developers around who do that sort of thing, no amount tightening the
restrictions imposed by your API is going to turn them into competent
programmers. They'll still produce garbage.
cout<<s<<endl;

return 0;
}

You cannot not do simpler. It is using a standard class (which is
developped by valuable people according to Scott Meyers ;-)). The class
must return pointer to raw data. Yet I can delete it and the above
program dumps in an unpleasant manner.


std::string doesn't prevent you from writing code like this. So who is
at fault? Scott Meyers's valuable people for writing a fragile API, or
you for doing something stupid?

Gavin Deane

Jan 31 '06 #10

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

Similar topics

2
9134
by: Martin Lucas-Smith | last post by:
Can anyone provide any suggestions/URLs for best-practice approaches to preventing SQL injection? There seems to be little on the web that I can find on this. Martin Lucas-Smith www.geog.cam.ac.uk/~mvl22 www.lucas-smith.co.uk Senior Computing Technician (Web Technician) Department of Geography, University of Cambridge (01223 3)33390
5
4617
by: Bruce | last post by:
I have a number of forms that do significant work based on variables POSTed from the form. What is the common method of detecting and preventing this work from being done when the form is POSTed as the result of the user clicking the Back or Reload buttons in the browser? --Bruce
8
2338
by: CJM | last post by:
How do people go about preventing the user from submitting a form for a 2nd time? For example, the user submits a form, clicks on the back button, and the submits the form again. I have used various techniques in the past (depending on circumstances) but I'd be interested in the techniques you guys currently use. Thanks --
18
6676
by: Tron Thomas | last post by:
Given the following information about memory management in C++: ----- The c-runtime dynamic memory manager (and most other commercial memory managers) has issues with fragmentation similar to a hard drive file system. Over time, the more often use call new/delete or alloc/free, there will be gaps and fragments in the heap. This can lead to inefficient use of available memory, as well as cache-hit inefficiencies.
1
1830
by: Wayne Aprato | last post by:
Is there an effective method of preventing users from accidentally or maliciously deleting the database file/files from a shared network drive? At the moment, I'm using a batch file to copy the data.mdb to another secure location every time a particular user who performs most of the data entry exits the database. Setting the windows permissions for the database folder to "read only" seems to create problems and data entry users obviously...
6
1565
by: Rey | last post by:
Howdy all. Am attempting to delete a large number of records (123K) from a table using: db.execute "delete from tblname" Then I double check (code below) to see if records still remain as during my testing they have...and that causes problems when the app reloads the table w/current data and encounters already existing keys...
1
1605
by: Eike | last post by:
Hi, I am unable to delete a subfolder that I have created programatically. I am using a modification of the apiSHFileOperation by Dev Ashish (http://www.mvps.org/access/api/api0026.htm) to copy the files. A File Copy function is called as part of a loop to copy a series of files from a variety of locations that are stored in the database. All the files are copied to a folder specified by the user. Once the user has used this folder (to...
2
1768
by: Nina | last post by:
Hi there, I've tried everything that I know to prevent usre resizing datagrid columns, but nothing works. Following are the code that I used. Please tell me what's wrong with them. Thank you. P.S.: dg is datagrid Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
15
2017
by: mathieu | last post by:
Hi, I have implemented a SmartPointer class following the implementation proposed by Bill Hubauer(*). But I also override the operator * () template<class ObjectType> class SmartPointer { public: operator ObjectType * () const
0
8991
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9544
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9324
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9247
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6074
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4606
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3313
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2783
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2215
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.