Board index » cppbuilder » Deleting pointers

Deleting pointers


2004-10-14 09:55:15 PM
cppbuilder106
I am trying to understand some things about pointers
1) Dereferencing pointers : I have a complex c++ builder project with Delphi
units, standard C units and C++ units. There is a heavy use
of pointers in each of these units. I understand I have to dereference
pointers after using them especially if the unit is accessed repeatedly
during
a program (?) In C I do *p=0. In C++ I do "delete[] ***p". Does
dereferencing fail? How so and how to avoid problems?
2) When creating pointers, or allocating the memory for pointers, why do
failures happen? Can it all be solved by dereferencing properly?
Thanks
Thomas
 
 

Re:Deleting pointers

On Thu, 14 Oct 2004 09:55:15 -0400, Thomas wrote:
Quote
In C++ I do "delete[] ***p".
use delete for pointers to single objects:
T * p = new T;
// do stuff
delete p;
use delete[] for arrays
T * a = new T[3];
// do stuff
delete [] a;
Much of the time you'll do better using smart pointers (e.g. auto_ptr,
and boost::shared_ptr etc
www.boost.org/libs/smart_ptr/smart_ptr.htm ) than new/delete and
new/delete[]
Quote
Does
dereferencing fail? How so and how to avoid problems?
Dereferencing a pointer succeeds if the pointer is valid.
Quote

2) When creating pointers, or allocating the memory for pointers, why do
failures happen?
Give an example please.
Quote
Can it all be solved by dereferencing properly?
Unlikely,
--
good luck,
liz
 

Re:Deleting pointers

Hi liz,
Thanks for your replies!
Quote
>In C++ I do "delete[] ***p".

use delete for pointers to single objects:

T * p = new T;
// do stuff
delete p;

use delete[] for arrays

T * a = new T[3];
// do stuff
delete [] a;
So if I understood correctly, even if I have a multidimensional array of
pointers like "int ***p"
I just use "delete[] p;" correct?
Quote

Much of the time you'll do better using smart pointers (e.g. auto_ptr,
and boost::shared_ptr etc
www.boost.org/libs/smart_ptr/smart_ptr.htm ) than new/delete and
new/delete[]
I will look into this, thanks!
Quote
>>
>2) When creating pointers, or allocating the memory for pointers, why do
>failures happen?

Give an example please.
I am trying to debug some access violation runtime errors in my program.
After doing some reading
on the net I read that if memory allocation of pointers fail then such
violation can occur. My C units
use "malloc" . I used malloc in the C++ units too because I wasnt sure if I
could exchange data with the
C units. (I'm a beginner in all of this!)
Thanks
Thomas
 

{smallsort}

Re:Deleting pointers

"Thomas" < XXXX@XXXXX.COM >writes:
Quote
So if I understood correctly, even if I have a multidimensional array of
pointers like "int ***p"
I just use "delete[] p;" correct?
If you allocated the internal arrays in your multidimensional array,
you have to delete each of them first. C++ pointer management is not
high level. For every allocation you need the correct corresponding
deallocation.
Skip some and you leak your objects. Delete incorrectly and you
corrupt your program and likely crash.
Be careful about mixing C and C++ allocations. Given a pointer out of
context, it's impossible to know how it was allocated and therefore
impossible to correctly determine how to deallocate it.
If it was allocated with C's malloc or calloc, you must call free. If
it was allocated with new, use delete. If it was allocated with
new[], use delete[]. If it is the address of a stack object, a global
variable, or other object that wasn't allocated, it should not be
deallocated. Unfortunately, it's entirely up to you to do proper
bookkeeping to know how the pointer needs to be treated.
That's where smart pointers come in. They're "smart" in that they
hold the pointer and know how to properly destroy them, provided
they're used correctly. For example, auto_ptr can not hold arrays
(even though it compiles, it is undefined what happens, but it's not
good!) Smart pointers help but are no substitute for being meticulous
and careful in your design. Get sloppy with pointers and your program
will be a horrible mess of crashes and mystery. :)
--
Chris (TeamB);
 

Re:Deleting pointers

On Thu, 14 Oct 2004 10:44:24 -0400, Thomas wrote:
Quote
So if I understood correctly, even if I have a multidimensional array of
pointers like "int ***p"
I just use "delete[] p;" correct?
No. You have to delete each dimension you allocate. And actually,
you'd be well advised to check std::vector.
e.g.
T **p;
p = new T*[d1];
for (int i = 0; i < d1; ++i)
{
p[i] = new T[d2];
}
// do stuff
for (int i = 0; i < d1; ++i)
{
delete[] p[i];
p[i] = 0;
}
delete p;
You're better off with:
typedef std::vector<T>TVec;
typedef std::vector< TVec>TArr;
TArr a(d1);
for (int i = 0; i < d1; ++i)
{
a[i].resize(d2);
}
or some such.
Quote
I am trying to debug some access violation runtime errors in my program.
After doing some reading
on the net I read that if memory allocation of pointers fail then such
violation can occur. My C units
use "malloc" . I used malloc in the C++ units too because I wasnt sure if I
could exchange data with the
C units. (I'm a beginner in all of this!)
You can exchange the pointers certainly.
If you use new/delete and new/delete[] you won't get invalid pointers.
If you use malloc you must check whether stuff was allocated:
T * p = malloc(sizeof(T));
if (p == NULL)
{
// bad!
}
you must also use free() to deallocate the memory
--
good luck,
liz
 

Re:Deleting pointers

"Thomas" < XXXX@XXXXX.COM >writes:
Quote
In C I do *p=0. In C++ I do "delete[] ***p".
These two operations have entirely different semantics, without any overlap.
Quote
Does dereferencing fail?
It can; if a pointer doesn't point to an object, dereferencing it will fail.
The program will have undefined behavior; anything can happen, including
the expected thing - unless you do a demo to your client :-)
Quote
How so and how to avoid problems?
- careful programming
- avoiding pointers in the first place
Quote
2) When creating pointers, or allocating the memory for pointers, why do
failures happen?
Because there is not enough memory left for the request, either the request
if for too much memory or because the available memory is already used.
Quote
Can it all be solved by dereferencing properly?
In some cases, yes. But just as a special case of careful programming.
 

Re:Deleting pointers

I think all of your experience really helps, so I think I'll describe the
situation and people here
could suggest what is the best thing to do.
I have a thousands of lines of C source code.The author of that code has
been very careful in dealing with
data and claims that it is error free, so I dont want to change any of it.
The source code contains hundreds
of functions of which I use only a dozen or so.
I have written a separate C function in a .c file to access the dozen
functions that I need. The C function
contains three dimensional arrays of double.
I have created a C++ builder project with a .cpp file that has the main code
and accesses the C function and
passes to it multimensional arrays and get back multidimensional arrays.
In addition I have kept global variable common to both the C and cpp units
(and are also pointers).
I am assuming that I cannot use smart pointers in C. What is the best way to
create the multidimensional array in C++
pass it to the C function and get back from the the C code multidimensional
arrays?
Should I avoid using global pointers and just return the data back with the
C function? (I am currently allowing the global
variable to be calculated within the C function and since it is global it is
visible in the C++ program)
Again, thanks to "Liz Albin","Chris Uzdavinis" and "Thomas Maeder" for your
extremely valuable suggestions.
Sincerely
Thomas
 

Re:Deleting pointers

I forgot to mention in my last post that I am dealing with 1,2,3, and 4
dimensional arrays
of varying size . Their size changes dynamically as the program progresses
and hence my use of
pointers.
Thomas
 

Re:Deleting pointers

"Thomas" < XXXX@XXXXX.COM >writes:
Quote
I forgot to mention in my last post that I am dealing with 1,2,3,
and 4 dimensional arrays of varying size . Their size changes
dynamically as the program progresses and hence my use of pointers.
Once you get to a few levels of pointers, it gets a lot harder to keep
things straight. :) So first of all, you need to determine WHO owns
the memory, who shall do all of the allocations and deallocations.
When you pass these arrays around, you need to keep clear who is
allowed to change the pointers, and who is allowed to change the
data. If the C application is doing the allocation, it should do all
the allocation, resizing, and deallocation. The C++ code should only
change the "doubles" in the arrays. Or vice versa.
So if the C++ code decides it needs to redimension the array, it'll
have to ask the C code to do it, and to give the C code the new
dimensions. That way your C++ code doesn't have to know HOW it was
allocated, and doesn't know how to actually do the changes. It only
knows WHEN to change, and to what size. Then it lets the C code "do
whatever is necessary" to fulfill that requirement.
Memory management gets ugly between different libraries and dlls.
It's a good idea to try to keep the same code that allocates something
to be the same code that destroys it. Frequently, this means the same
source file that allocates is the same source file that has the logic
for deallocating. That keeps the logic together.
--
Chris (TeamB);
 

Re:Deleting pointers

Quote
"Thomas" < XXXX@XXXXX.COM >writes:

>I forgot to mention in my last post that I am dealing with 1,2,3,
>and 4 dimensional arrays of varying size . Their size changes
>dynamically as the program progresses and hence my use of pointers.

Once you get to a few levels of pointers, it gets a lot harder to keep
things straight. :) So first of all, you need to determine WHO owns
the memory, who shall do all of the allocations and deallocations.
When you pass these arrays around, you need to keep clear who is
allowed to change the pointers, and who is allowed to change the
data. If the C application is doing the allocation, it should do all
the allocation, resizing, and deallocation. The C++ code should only
change the "doubles" in the arrays. Or vice versa.
What about overloading new/delete (or using placement form) for array to
allocate memory for elements on a private heap and then just destroy heap
when it's not longer used? This is not suitable for classes with
complex-behaiving destructors, but for something as simple as array of
doubles it would work like charm.
Regarding mixing C/C++ memory allocation... Well, if you know for sure that
malloc was called to acquire memory, nothing is wrong with calling free on
it.
void * new[ ]( unsigned int _uiSize )
{
return( ::malloc( _uiSize ) );
}
void delete[]( void *_pvMemory )
{
::free( _pvMemory );
}
char *ptr = new char[ 100 ];
ptr = ::realloc( ptr, 200 );
delete[]( ptr );
I cannot imagine compiler that would generate inadequate code for this. Such
"dangerous" reallocation will work for user-defined classes with compiler
generated copy-constructor/destructor as well.
Now you can ridicule me ;).
Azazello.