LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-07-2014, 11:33 AM   #16
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940

Also ... even with all the goodness that C++ provides in an attempt to make the process of handling memory "easier," there are still a few points to keep in mind:

(1) Never "mix metaphors." When in C++ land, do as C++ does. Do not call C-style memory allocation routines directly.

(2) It is always a good idea to make sure that allocated memory blocks contain all-zero, even if you find that you must memset() it yourself.

(3) When you free or otherwise dispose-of a memory block, you should always explicitly set the pointer's value to NULL, in the very next statement!.

In general, two things will burn you in the ... a "stale pointer," and a memory-block which contains unpredictable but garbage content. You need to make a (self-imposed) cardinal rule which says: "if a pointer is not-NULL, it must point to something valid. Otherwise, it must be known-NULL."

It's usually easy to accomplish these three things, and more, with a simple "wrapper" library that enhances calls to the underlying system-library routines. For instance,immediately before deallocating a block of memory, they fill it with the byte-string $DEADBEEF. (And, it peeks at addresses to thereby detect, and prevent, "double frees.") It also puts "eyecatchers" on both sides of each allocated block, and wipes-out (changes ...) those eyecatchers upon free. So, if storage gets "scribbled," bang ... the problem shows-up immediately.

The overhead of all this is so negligible that I routinely "leave it in." It's tremendously useful for an application to be able to provide these kinds of self-safeguards "in production," and it's basically free-of-cost to be able to do just that.

By imposing just a little bit of additional discipline upon your program's use of dynamic storage, you can greatly improve its reliability and diagnosability. "Unpredictable memory-content is not your friend."

Last edited by sundialsvcs; 05-08-2014 at 12:47 PM.
 
1 members found this post helpful.
Old 05-07-2014, 12:03 PM   #17
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by NevemTeve View Post
Clearing the malloc-ed/new-ed memory still might be a good idea, as valgind seems to read your memory-areas, so non-initialized memories might cause false valgrind messages.
This may cause a legitimate warnings to be silenced though, because Valgrind will always assume the memory is initialised (since it has been zeroed).

Besides, new calls constructor of the type anyway.

Quote:
Originally Posted by sundialsvcs View Post
(2) It is always a good idea to make sure that allocated memory blocks contain all-zero, even if you find that you must memset() it yourself.
I must disagree. It is a good idea to initialise the memory to sensible state, but that does not have, and often is not, “all-zero”. Also, for more complex types the term “all-zero” is meaningless. And like I've said, new will call constructor for you. You're statement is just too simplistic to be true in general.

Quote:
Originally Posted by sundialsvcs View Post
(3) When you free or otherwise dispose-of a memory block, you should always explicitly set the pointer's value to NULL, in the very next statement!.
This of course assuming the pointer will hang around for a while. It's usually no point in setting pointer to NULL in a destructor for instance or at the end of a function.

Either way, as it was mentioned earlier, std::unique_ptr is your friend. If used correctly, it makes it possible to never have to call delete oneself, which greatly reduces risks of memory leaks.

Quote:
Originally Posted by sundialsvcs View Post
I often work with debugging-routines that go even farther than this. Immediately before deallocating a block of memory, they fill it with the byte-string $DEADBEEF. (And, it peeks at addresses to thereby detect, and prevent, "double frees.") It also puts "eyecatchers" on both sides of each allocated block, and wipes-out (changes ...) those eyecatchers upon free. So, if storage gets "scribbled," bang ... the problem shows-up immediately. The overhead of all this is so negligible that I routinely "leave it in."
This however should not be part of the code that calls new/delete. If so desired, new could be overwritten to do all those things, but expecting programmer to do this when dealing with dynamic data is ridiculous.
 
1 members found this post helpful.
Old 05-08-2014, 12:57 PM   #18
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940
Quote:
I must disagree. It is a good idea to initialise the memory to sensible state, but that does not have, and often is not, “all-zero”. Also, for more complex types the term “all-zero” is meaningless. And like I've said, new will call constructor for you. You're statement is just too simplistic to be true in general.
And I'll respectfully stand by my statement. Start by setting the whole memory-block to known-zero, then if necessary run whatever constructors you need, all automagically. This guarantees that the content of the entire block is always known, in all cases. I've lost count of the number of times that has saved my ...

Quote:
This of course assuming the pointer will hang around for a while. It's usually no point in setting pointer to NULL in a destructor for instance or at the end of a function.
Obviously a local variable that is going out-of-scope is, well, going out of scope. Yes. But, watch out about those destructors! Destructors are called in a hierarchy of destructors, and it is quite easy for an outer-level destructor to, unbeknownst to you, "trust" that pointer-value. If the pointer is contained in a property of the object, then yes, I would "immediately set it to NULL."

And my long experience has taught me to be very gun-shy about this sort of thing. I can easily spare a few dozen more micro-seconds, but I have literally lost $10,000.00 (USD) in hard (not "funny") money to a double-free problem caused in ... a nested destructor. The [i](Dephi) code looked like this: (in vendor-supplied code)
Code:
p1.free;
p2.free;
p1 := nil;
p2 := nil;
And the fix was to make it look like this:
Code:
p1.free; p1 := nil;
p2.free; p2 := nil;
But it came too late to save the $10,000.00.

(No comments regarding the remainder of your points raised.)
 
Old 05-11-2014, 09:38 AM   #19
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by sundialsvcs View Post
And I'll respectfully stand by my statement. Start by setting the whole memory-block to known-zero, then if necessary run whatever constructors you need, all automagically. This guarantees that the content of the entire block is always known, in all cases. I've lost count of the number of times that has saved my ...
If the all-bit-zero state is not a valid state of an object, setting the whole block to zero does not prevent bugs. Yet it prevents various tools (for example Coverity) from determining whether uninitialised memory is accessed.
 
Old 05-11-2014, 04:18 PM   #20
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940
It is far better to make sure that uninitialized memory does not get accessed, in the first place. If you are disciplined about making certain that (especially) all dynamically-allocated memory blocks have known NULL content, and if you immediately destroy "stale" pointers the instant they become stale, you will virtually eliminate this concern.

Now, I'm not here to get into any sort of dogmatic argument. I'm simply describing what works extremely well for me. You adopt the discipline that either a pointer is known to point to a valid, allocated, initialized memory-block, or it is NULL.

I also suggest that you allocate a variable called slop at the end of each memory block. It is literally there to make the block about 8 (known-zero) bytes longer than you know that it needs to be. Almost always, when a memory reference is "off," it's "off by one." Unfortunately, that can "scribble" (ahem ...) "on" the memory-allocation areas used by malloc(), leading to unpredictable crashes. A little "slop" is very cheap insurance. It enables you to find these bugs during testing, and to stomp them out.
 
Old 05-11-2014, 07:01 PM   #21
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by mina86 View Post
If the all-bit-zero state is not a valid state of an object, setting the whole block to zero does not prevent bugs.
It would make the occurrence of bugs more deterministic though.

Quote:
Yet it prevents various tools (for example Coverity) from determining whether uninitialised memory is accessed.
That seems like a good argument to disable this feature while running such a tool.
 
Old 05-12-2014, 11:55 AM   #22
ejspeiro
Member
 
Registered: Feb 2011
Distribution: Ubuntu 14.04 LTS (Trusty Tahr)
Posts: 203

Original Poster
Rep: Reputation: 26
Dear all, this has been an amazing thread... I will call it solved.

Thanks a lot!
 
Old 05-12-2014, 12:06 PM   #23
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by ntubski View Post
That seems like a good argument to disable this feature while running such a tool.
What are we talking about here? Are we talking about code like this one:
Code:
ptr = malloc(sizeof *ptr);
memset(ptr, 0, sizeof *ptr);
or are we talking about a specialised implementation of malloc/free (or new/delete) that zeroes the memory?

In the former case, adding code to be able to disable the zeroing when tools like Valgrind or Coverity are used, is a terrible idea since it complicates the code even more:
Code:
ptr = malloc(sizeof *ptr);
#ifndef DEBUG_BUILD
  memset(ptr, 0, sizeof *ptr);
#endif
If we're talking about the latter, then I would much rather a debug implementation of malloc filled memory with 0xdeadbeef and free with 0xfee1dead. That would make bugs much more apparent.

Adding zeroing inside of malloc would on the other hand make the code less portable since programmer would start depending on the fact that allocated memory is zeroed which is not guaranteed by the standard.
 
  


Reply

Tags
c++, free, pointers



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: GNU Free Call: A Proposed Free Phone To Skype LXer Syndicated Linux News 0 03-15-2011 04:00 PM
LXer: GNU/Linux and freedom: non-free software hidden in your GNU/Linux distribution LXer Syndicated Linux News 0 04-02-2010 11:21 PM
Slackware, GNU and free software. camphor Slackware 16 02-11-2010 07:54 AM
LXer: Free implementation of the VMware cluster file system LXer Syndicated Linux News 0 03-06-2009 06:20 PM
Implementation of free() manas_sem Programming 1 03-08-2007 07:48 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration