Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why not realloc(&ptr, ...) and free(&ptr)?

Reply
Thread Tools

Why not realloc(&ptr, ...) and free(&ptr)?

 
 
James Harris
Guest
Posts: n/a
 
      08-05-2013
I cannot get my head round why calls to realloc and free do not have a
pointer to the initial pointer passed to them as in the following if ptr had
been returned by malloc.

retcode = realloc(&ptr, new_size);
free(&ptr);

The idea being that if realloc could reallocate the space it would update
the pointer and return true. If it could not reallocate the space it would
leave the pointer unchanged and return false.

In the case of free() the idea is that it would set the pointer to NULL.

Anyone know why the above two calls were designed the way they were?

James


 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      08-05-2013
On 08/05/2013 05:30 AM, James Harris wrote:
> I cannot get my head round why calls to realloc and free do not have a
> pointer to the initial pointer passed to them as in the following if ptr had
> been returned by malloc.
>
> retcode = realloc(&ptr, new_size);
> free(&ptr);
>
> The idea being that if realloc could reallocate the space it would update
> the pointer and return true. If it could not reallocate the space it would
> leave the pointer unchanged and return false.
>
> In the case of free() the idea is that it would set the pointer to NULL.
>
> Anyone know why the above two calls were designed the way they were?


You mean like this?

char *pc = malloc(5*sizeof *pi);
long double _Complex *pd = malloc(5*sizeof *pd);
free(&pc);
free(&pd);

Do you see the problem there? pc and pd have incompatible types; those
types might have different sizes - there are real-world machines where
that is the case. Even if they were the same size, they might have
incompatible representations - though I don't know of any real-world
example of that.
Many people think that since void* can accommodate any kind of pointer
to an object type, void** can accommodate any kind of pointer to a
pointer to an object type, but C doesn't work that way. It couldn't work
that way unless it were changed to require all pointers to object types
to have the same representation and alignment. If free() were changed to
take a void**, it would have to used this way:
void * temp = pc;
free(&temp);
temp = pd;
free(&temp);
This not only makes it more complicated to use free(), but it also
eliminates the supposed advantage of this change: pc and pd are still
not null.

Even if C were changed to require all pointers to have the same
representation, so that void** could work that way, this still would
violate one of the design principles of C. You shouldn't have to pay
for the parts of C that you don't use. Well designed code often doesn't
need to waste time nulling such a pointer, because the pointer will
never be used again during the time that it would have been null. That's
true of most of the code I've written that uses free(). Why should code
that has been written that way pay the cost of having free() waste it's
time setting the pointer to null?
If you do write a lot of code that requires nulling the pointer, you can
always write a macro that wraps free(), and nulls the pointer. That way,
you get the nulling that you need, while my code still avoids wasting
time on nulling that I don't need. I'd have no great objection to adding
such a macro to the C standard library, but it's so trivial to write one
on your own that I doubt it would ever be approved.

Also, keep in mind that a nulling version of free() would not
necessarily do the entire job that needs to be done. In a typical
program where you would need to null the pointer, there's often multiple
pointers pointing into various locations inside the block of allocated
memory. They all need to be nulled, if there's a chance they'll be used
again before they've been set to a different non-null value.
--
James Kuyper
 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      08-05-2013
On 8/5/2013 05:30, James Harris wrote:
> I cannot get my head round why calls to realloc and free do not have a
> pointer to the initial pointer passed to them as in the following if ptr had
> been returned by malloc.
>
> retcode = realloc(&ptr, new_size);
> free(&ptr);
>
> The idea being that if realloc could reallocate the space it would update
> the pointer and return true. If it could not reallocate the space it would
> leave the pointer unchanged and return false.
>
> In the case of free() the idea is that it would set the pointer to NULL.
>
> Anyone know why the above two calls were designed the way they were?
>


What James Kuyper said. If you'd shared the declaration of 'ptr' in
your code, it might've been easier to point to. (No pun intended.)

Also consider:

void func(void) {
long * lp;

lp = malloc(sizeof *lp);
/* ... */
free(lp);
lp = NULL;
}

There's not really a need to set 'lp' to a null pointer value, here, as
its lifetime is about to expire. You might want to for security
reasons, perhaps, but then it does cost time.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-05-2013
"James Harris" <(E-Mail Removed)> writes:

> I cannot get my head round why calls to realloc and free do not have a
> pointer to the initial pointer passed to them as in the following if ptr had
> been returned by malloc.
>
> retcode = realloc(&ptr, new_size);
> free(&ptr);
>
> The idea being that if realloc could reallocate the space it would update
> the pointer and return true. If it could not reallocate the space it would
> leave the pointer unchanged and return false.
>
> In the case of free() the idea is that it would set the pointer to NULL.
>
> Anyone know why the above two calls were designed the way they were?


Types have been mentioned, but there's another issue with realloc. It
has to copy the contents of the old memory to the new, but that's wasted
effort if you don't want that behaviour. For example, if it's a hash
table you will want the old elements re-hashed for the new size, not
simply copied into the old offsets. Worse, having them copied makes the
re-hashing a pain in the neck.

And when sizing down, you might want to do something to the old extra
elements (free them, for example) but that will now have to be done
before the realloc and you'll then have problems if the re-size fails.

All in all, it's simpler to re-size the memory at let the programmer
decide what needs to be done with both the old and the new allocation.

--
Ben.
 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-05-2013
"James Kuyper" <(E-Mail Removed)> wrote in message
news:kto16s$4kp$(E-Mail Removed)...
> On 08/05/2013 05:30 AM, James Harris wrote:
>> I cannot get my head round why calls to realloc and free do not have a
>> pointer to the initial pointer passed to them as in the following if ptr
>> had
>> been returned by malloc.
>>
>> retcode = realloc(&ptr, new_size);
>> free(&ptr);
>>
>> The idea being that if realloc could reallocate the space it would update
>> the pointer and return true. If it could not reallocate the space it
>> would
>> leave the pointer unchanged and return false.
>>
>> In the case of free() the idea is that it would set the pointer to NULL.
>>
>> Anyone know why the above two calls were designed the way they were?

>
> You mean like this?
>
> char *pc = malloc(5*sizeof *pi);
> long double _Complex *pd = malloc(5*sizeof *pd);
> free(&pc);
> free(&pd);
>
> Do you see the problem there? pc and pd have incompatible types; those
> types might have different sizes - there are real-world machines where
> that is the case. Even if they were the same size, they might have
> incompatible representations - though I don't know of any real-world
> example of that.


So, in summary, pointer to type A and pointer to type B might have different
sizes and/or different representations of null?

Trying to understand the ramifications of this.....

AIUI malloc returns pointer to void. I suppose that, on machines where
needed, the compiler inserts conversions from malloc's return (which could
be null) in to a pointer to the right type. It knows the type of the
variable being assigned to so can add instructions to convert malloc's
return to a different representation if needed.

Similarly, when a program calls free() on a pointer the compiler knows that
that pointer is of type X and can perform any conversions back to the format
of a void pointer before calling free().

And when assigning NULL to a pointer or comparing a pointer with NULL the
compiler can convert length and NULL-representation as necessary.

OK. I think I've got that.

So if pointers on a given architecture were always all the same size and
always had the same representation of NULL no matter what they were pointing
at it would have been possible to call free(&p) because the free routine
could have included

*p = NULL;

But since the above cannot be guaranteed free() could not set the pointer to
null. On those odd machines there would be different NULLs.

Would it still have been OK for free to return NULL so that code could
include the following?

p = free(p);

I know that it does not return NULL. I am trying to understand the design a
bit better.

Can you remember any of the machines where pointers to different types had
different sizes? If you can I'd like to look into some more about how they
worked and which would still be in use.

> Many people think that since void* can accommodate any kind of pointer
> to an object type, void** can accommodate any kind of pointer to a
> pointer to an object type, but C doesn't work that way. It couldn't work
> that way unless it were changed to require all pointers to object types
> to have the same representation and alignment. If free() were changed to
> take a void**, it would have to used this way:
> void * temp = pc;
> free(&temp);
> temp = pd;
> free(&temp);
> This not only makes it more complicated to use free(), but it also
> eliminates the supposed advantage of this change: pc and pd are still
> not null.


I don't understand this. If all pointers were the same size and represented
NULL in the same way why couldn't free(&p) work? It could both get and set
the pointer that p pointed at.

If, on the other hand, you mean the above code to be used where pointers
were not of the same size then the problem is that there's no way - sensible
or otherwise - to dereference a void * so I cannot see how the code could
work.

In terms of the design of free(), if pointers had different sizes either
free would need an extra parameter identifying the pointer type or there
would need to be different versions of free, one per pointer type - or at
least one per representation of NULL. AFAICS it's OK for mallo to return
void * because the caller knows what type conversions to carry out; but with
free() the callee would be expected to deal with the differences - something
that it could not do without knowing the pointer type.

Either way, I can see the point about machines with pointer types which
differ in size or null or both.

>
> Even if C were changed to require all pointers to have the same
> representation, so that void** could work that way, this still would
> violate one of the design principles of C. You shouldn't have to pay
> for the parts of C that you don't use. Well designed code often doesn't
> need to waste time nulling such a pointer, because the pointer will
> never be used again during the time that it would have been null. That's
> true of most of the code I've written that uses free(). Why should code
> that has been written that way pay the cost of having free() waste it's
> time setting the pointer to null?


I'm less sure I agree with this. Clearing a pointer (p = NULL) would be
insignificant when compared with the cost of just calling the free routine
even if the free routine were to do the absolute minimum. Further, there are
many examples in the C library of distributed costs. For example, a call to
printf returns an int that's often not needed. Would you propose another set
of printf routines which did not return a value on the basis that it could
save on costs? In fact the whole suite of printf routines are probably an
order of magnitude (or more) more expensive than they need to be for most of
what they are used for, because they cope with the general case.

> If you do write a lot of code that requires nulling the pointer, you can
> always write a macro that wraps free(), and nulls the pointer. That way,
> you get the nulling that you need, while my code still avoids wasting
> time on nulling that I don't need. I'd have no great objection to adding
> such a macro to the C standard library, but it's so trivial to write one
> on your own that I doubt it would ever be approved.
>
> Also, keep in mind that a nulling version of free() would not
> necessarily do the entire job that needs to be done. In a typical
> program where you would need to null the pointer, there's often multiple
> pointers pointing into various locations inside the block of allocated
> memory. They all need to be nulled, if there's a chance they'll be used
> again before they've been set to a different non-null value.


Sure. That applies any time a region is realloced as well.

By the way, I take it your comments about free apply to realloc too. AFAICT
they do, i.e. realloc couldn't know what to change a pointer to on machines
where there were different sizes of pointer. Again, it could be done as
above if all pointers on a given machine were of the same size and same NULL
(nearly all machines in use today?).

Pity - it would be especially convenient for realloc where the return code
could indicat success or failure.

James


 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      08-05-2013
On 8/5/2013 11:40, James Harris wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:kto16s$4kp$(E-Mail Removed)...
>> On 08/05/2013 05:30 AM, James Harris wrote:
>>> I cannot get my head round why calls to realloc and free do not have a
>>> pointer to the initial pointer passed to them as in the following if ptr
>>> had
>>> been returned by malloc.
>>>
>>> retcode = realloc(&ptr, new_size);
>>> free(&ptr);
>>>
>>> The idea being that if realloc could reallocate the space it would update
>>> the pointer and return true. If it could not reallocate the space it
>>> would
>>> leave the pointer unchanged and return false.
>>>
>>> In the case of free() the idea is that it would set the pointer to NULL.
>>>
>>> Anyone know why the above two calls were designed the way they were?

>>
>> You mean like this?
>>
>> char *pc = malloc(5*sizeof *pi);
>> long double _Complex *pd = malloc(5*sizeof *pd);
>> free(&pc);
>> free(&pd);
>>
>> Do you see the problem there? pc and pd have incompatible types; those
>> types might have different sizes - there are real-world machines where
>> that is the case. Even if they were the same size, they might have
>> incompatible representations - though I don't know of any real-world
>> example of that.

>
> So, in summary, pointer to type A and pointer to type B might have different
> sizes and/or different representations of null?
>
> Trying to understand the ramifications of this.....
>
> AIUI malloc returns pointer to void. I suppose that, on machines where
> needed, the compiler inserts conversions from malloc's return (which could
> be null) in to a pointer to the right type. It knows the type of the
> variable being assigned to so can add instructions to convert malloc's
> return to a different representation if needed.
>


It's not special for 'malloc', it's a specialty of 'void *'.

> Similarly, when a program calls free() on a pointer the compiler knows that
> that pointer is of type X and can perform any conversions back to the format
> of a void pointer before calling free().
>
> And when assigning NULL to a pointer or comparing a pointer with NULL the
> compiler can convert length and NULL-representation as necessary.
>
> OK. I think I've got that.
>
> So if pointers on a given architecture were always all the same size and
> always had the same representation of NULL no matter what they were pointing
> at it would have been possible to call free(&p) because the free routine
> could have included
>
> *p = NULL;
>


Why do you care about assigning the pointer to a null pointer value? Is
it because you're in a loop, or something? Security?

> But since the above cannot be guaranteed free() could not set the pointer to
> null. On those odd machines there would be different NULLs.
>
> Would it still have been OK for free to return NULL so that code could
> include the following?
>
> p = free(p);
>


It seems to me that it's more common that nobody cares what happens to
'p' after its value has been passed to 'free'. So then it's more common
to see:

free(p);

If 'free' had a return value, then this code would ignore that return
value, and people with their compiler-warnings turned up would have to
do something like:

(void) free(p);

> I know that it does not return NULL. I am trying to understand the design a
> bit better.
>
> Can you remember any of the machines where pointers to different types had
> different sizes? If you can I'd like to look into some more about how they
> worked and which would still be in use.
>
>> Many people think that since void* can accommodate any kind of pointer
>> to an object type, void** can accommodate any kind of pointer to a
>> pointer to an object type, but C doesn't work that way. It couldn't work
>> that way unless it were changed to require all pointers to object types
>> to have the same representation and alignment. If free() were changed to
>> take a void**, it would have to used this way:
>> void * temp = pc;
>> free(&temp);
>> temp = pd;
>> free(&temp);
>> This not only makes it more complicated to use free(), but it also
>> eliminates the supposed advantage of this change: pc and pd are still
>> not null.

>
> I don't understand this. If all pointers were the same size and represented
> NULL in the same way why couldn't free(&p) work? It could both get and set
> the pointer that p pointed at.
>


Beyond sizes, C cares about types. '&p' will yield a 'type-of-p *'. If
'p' is a 'long *', then '&p' will yield a 'long **'.

> If, on the other hand, you mean the above code to be used where pointers
> were not of the same size then the problem is that there's no way - sensible
> or otherwise - to dereference a void * so I cannot see how the code could
> work.
>
> In terms of the design of free(), if pointers had different sizes either
> free would need an extra parameter identifying the pointer type or there
> would need to be different versions of free, one per pointer type - or at
> least one per representation of NULL. AFAICS it's OK for mallo to return
> void * because the caller knows what type conversions to carry out; but with
> free() the callee would be expected to deal with the differences - something
> that it could not do without knowing the pointer type.
>
> Either way, I can see the point about machines with pointer types which
> differ in size or null or both.
>
>>
>> Even if C were changed to require all pointers to have the same
>> representation, so that void** could work that way, this still would
>> violate one of the design principles of C. You shouldn't have to pay
>> for the parts of C that you don't use. Well designed code often doesn't
>> need to waste time nulling such a pointer, because the pointer will
>> never be used again during the time that it would have been null. That's
>> true of most of the code I've written that uses free(). Why should code
>> that has been written that way pay the cost of having free() waste it's
>> time setting the pointer to null?

>
> I'm less sure I agree with this. Clearing a pointer (p = NULL) would be
> insignificant when compared with the cost of just calling the free routine
> even if the free routine were to do the absolute minimum. Further, there are
> many examples in the C library of distributed costs. For example, a call to
> printf returns an int that's often not needed. Would you propose another set
> of printf routines which did not return a value on the basis that it could
> save on costs? In fact the whole suite of printf routines are probably an
> order of magnitude (or more) more expensive than they need to be for most of
> what they are used for, because they cope with the general case.
>


But why bother clearing the pointer? Do you initialize it? If not,
then why the asymmetric treatment?

while (cond) {
void * vp = malloc(4);
/* ...Test and do work... */
free(vp);
vp = NULL;
}

Clearing the pointer here is a waste, because it's going to be
initialized on the next iteration.

>> If you do write a lot of code that requires nulling the pointer, you can
>> always write a macro that wraps free(), and nulls the pointer. That way,
>> you get the nulling that you need, while my code still avoids wasting
>> time on nulling that I don't need. I'd have no great objection to adding
>> such a macro to the C standard library, but it's so trivial to write one
>> on your own that I doubt it would ever be approved.
>>
>> Also, keep in mind that a nulling version of free() would not
>> necessarily do the entire job that needs to be done. In a typical
>> program where you would need to null the pointer, there's often multiple
>> pointers pointing into various locations inside the block of allocated
>> memory. They all need to be nulled, if there's a chance they'll be used
>> again before they've been set to a different non-null value.

>
> Sure. That applies any time a region is realloced as well.
>
> By the way, I take it your comments about free apply to realloc too. AFAICT
> they do, i.e. realloc couldn't know what to change a pointer to on machines
> where there were different sizes of pointer. Again, it could be done as
> above if all pointers on a given machine were of the same size and same NULL
> (nearly all machines in use today?).
>
> Pity - it would be especially convenient for realloc where the return code
> could indicat success or failure.


'realloc' does indicate success or failure. It has one failure value
and many success values.

Something you might not be aware of: C says that a pointer's value
becomes indeterminate after that value has been passed to 'free'. So given:

void * vp1 = malloc(4);
void * vp2 = vp1;
void * vp3 = vp2;
free(vp1);

All of these pointers contain indeterminate values after the call to
'free'. This is because the lifetime of the pointed-to object has
expired, if I recall correctly.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      08-05-2013
In article <ktok4a$c4v$(E-Mail Removed)>,
Shao Miller <(E-Mail Removed)> wrote:
....
>Why do you care about assigning the pointer to a null pointer value? Is
>it because you're in a loop, or something? Security?


The usual reason is so that the code can determine that the pointer has
been freed. I.e., it acts as a sentinel value. Among other things, this
could be used to implement parameter verification; a routine could check to
see if a passed-in-value was NULL and issue an error message like:

"p is NULL. Perhaps it has been free'd..."

....
>Something you might not be aware of: C says that a pointer's value
>becomes indeterminate after that value has been passed to 'free'. So given:
>
> void * vp1 = malloc(4);
> void * vp2 = vp1;
> void * vp3 = vp2;
> free(vp1);
>
>All of these pointers contain indeterminate values after the call to
>'free'. This is because the lifetime of the pointed-to object has
>expired, if I recall correctly.


Beg to differ. I think that *de-refencing* a pointer value after it has
been free'd is, of course, UB, but the pointer itself cannot change,
because of C's call-by-value semantics.

I.e., in your example above, the value of vp1 cannot be changed as a result
of being passed to free().

--
This is the GOP's problem. When you're at the beginning of the year
and you've got nine Democrats running for the nomination, maybe one or
two of them are Dennis Kucinich. When you have nine Republicans, seven
or eight of them are Michelle Bachmann.
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      08-05-2013
On 8/5/2013 13:00, Kenny McCormack wrote:
> In article <ktok4a$c4v$(E-Mail Removed)>,
> Shao Miller <(E-Mail Removed)> wrote:
> ...
>> Why do you care about assigning the pointer to a null pointer value? Is
>> it because you're in a loop, or something? Security?

>
> The usual reason is so that the code can determine that the pointer has
> been freed. I.e., it acts as a sentinel value. Among other things, this
> could be used to implement parameter verification; a routine could check to
> see if a passed-in-value was NULL and issue an error message like:
>
> "p is NULL. Perhaps it has been free'd..."
>


I see.

> ...
>> Something you might not be aware of: C says that a pointer's value
>> becomes indeterminate after that value has been passed to 'free'. So given:
>>
>> void * vp1 = malloc(4);
>> void * vp2 = vp1;
>> void * vp3 = vp2;
>> free(vp1);
>>
>> All of these pointers contain indeterminate values after the call to
>> 'free'. This is because the lifetime of the pointed-to object has
>> expired, if I recall correctly.

>
> Beg to differ. I think that *de-refencing* a pointer value after it has
> been free'd is, of course, UB, but the pointer itself cannot change,
> because of C's call-by-value semantics.
>
> I.e., in your example above, the value of vp1 cannot be changed as a result
> of being passed to free().
>


Nah, C explicitly does state[6.2.4p2] that this is an exception to the
usual "callee cannot affect the caller's objects", because it's actually
affecting the set of all pointer values; which are good and which are
bad, m'kay? Doing printf("%p", vp3) after the 'free' might attempt to
load the value of 'vp3' into an address register and the CPU notices
that this does not address any storage, so it's a "mistake."

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      08-05-2013
On 05-Aug-13 12:00, Kenny McCormack wrote:
> In article <ktok4a$c4v$(E-Mail Removed)>,
> Shao Miller <(E-Mail Removed)> wrote:
>> Something you might not be aware of: C says that a pointer's value
>> becomes indeterminate after that value has been passed to 'free'.
>> So given:
>>
>> void * vp1 = malloc(4);
>> void * vp2 = vp1;
>> void * vp3 = vp2;
>> free(vp1);
>>
>> All of these pointers contain indeterminate values after the call to
>> 'free'. This is because the lifetime of the pointed-to object has
>> expired, if I recall correctly.

>
> Beg to differ. I think that *de-refencing* a pointer value after it
> has been free'd is, of course, UB, but the pointer itself cannot
> change, because of C's call-by-value semantics.


The value of vp1, vp2 and vp3 does not change after calling free(), but
those existing values all become indeterminate.

For instance, merely loading an indeterminate value into an address
register can fail because that address value no longer refers to any
valid object. You don't need to dereference it to cause problems.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-05-2013
"Shao Miller" <(E-Mail Removed)> wrote in message
news:ktok4a$c4v$(E-Mail Removed)...

....

>> So if pointers on a given architecture were always all the same size and
>> always had the same representation of NULL no matter what they were
>> pointing
>> at it would have been possible to call free(&p) because the free routine
>> could have included
>>
>> *p = NULL;
>>

>
> Why do you care about assigning the pointer to a null pointer value? Is
> it because you're in a loop, or something? Security?


A loop, no. Security, yes. Since the pointer value is no longer valid
setting it to null makes that clear to any later code. It could also be
passed to realloc which would then behave as malloc. Of course, it's
programmer responsibilty to handle any other pointers to the same area.

>
>> But since the above cannot be guaranteed free() could not set the pointer
>> to
>> null. On those odd machines there would be different NULLs.
>>
>> Would it still have been OK for free to return NULL so that code could
>> include the following?
>>
>> p = free(p);
>>

>
> It seems to me that it's more common that nobody cares what happens to 'p'
> after its value has been passed to 'free'. So then it's more common to
> see:
>
> free(p);
>
> If 'free' had a return value, then this code would ignore that return
> value, and people with their compiler-warnings turned up would have to do
> something like:
>
> (void) free(p);


If the compiler warned about that wouldn't it also warn about

printf("x");

Having to declare

(void) printf("x");

would be unusual.

Incidentally, I was once told casts were a bad idea (TM) as they mask other
issues. Maybe a compiler should complain about them too!

James


 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
difference between *ptr++ and ++*ptr ? Jason C Programming 19 05-19-2005 04:50 PM
is (!ptr) or (ptr) valid way to check for NULL or NOT NULL? G Fernandes C Programming 9 02-27-2005 03:07 AM
what's the difference between delete ptr and ptr=0 -dont they accomplish the same Sid C++ 5 07-29-2004 03:42 AM
Re: realloc, need to free old ptr? Christopher Benson-Manica C Programming 4 09-01-2003 09:26 PM



Advertisments