By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,264 Members | 1,277 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,264 IT Pros & Developers. It's quick & easy.

Modifying pointers of unknown type via a function call

P: n/a
I'm trying to write a function that does some realloc-style
modification of a pointer. The function itself works, but I'm having
some problems with the prototype. This is a simple example of the sort
of thing I want to do (not the complete code, that works but is
technically UB).

#include <stdlib.h>

void indirectmalloc(void** ptr, size_t s)
{
*ptr=malloc(s);
return;
}

int main(void)
{
char* a;
int* b;
indirectmalloc(&a);
indirectmalloc(&b);
free(a);
free(b);
return 0;
}

but although all pointers are freely castable to and from void*, not
all pointers-to-pointers are freely castable to and from void**, so
this is UB.
One compiler I use allows &(void*)a, but this is nonstandard. Is there
a portable way of doing this without relying on temporary void*s?
Should I use a #define macro instead? Although there are obviously
easier ways of writing the above code, I'd like to do something like
this (my actual code is more complicated; I'm not posting it because it
works, just invokes UB which happens to not be a problem on my
compiler).

Apr 13 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
ais523 wrote:
ais523 wrote:
I'm trying to write a function that does some realloc-style
modification of a pointer. The function itself works, but I'm having
some problems with the prototype. This is a simple example of the sort
of thing I want to do (not the complete code, that works but is
technically UB).
It's in the FAQ http://c-faq.com/ptrs/genericpp.html

If you want to do realloc type stuff, do it the way realloc does it.
#include <stdlib.h>

void indirectmalloc(void** ptr, size_t s)
{
*ptr=malloc(s);
return;
}
Why not return the pointer as malloc does? There is no need in this
example to pass in a pointer to a pointer.
int main(void)
{
char* a;
int* b;

#if 0
indirectmalloc(&a);
indirectmalloc(&b);

Sorry, that should have been
#endif
indirectmalloc(&a, sizeof *a);
indirectmalloc(&b, sizeof *b);


This is why you should always copy and paste the code you actually
compile from your editor.
free(a);
free(b);
return 0;
}

but although all pointers are freely castable to and from void*, not
all pointers-to-pointers are freely castable to and from void**, so
this is UB.
One compiler I use allows &(void*)a, but this is nonstandard. Is there
a portable way of doing this without relying on temporary void*s?
No.
Should I use a #define macro instead? Although there are obviously
easier ways of writing the above code, I'd like to do something like
this (my actual code is more complicated; I'm not posting it because it
works, just invokes UB which happens to not be a problem on my
compiler).


Change the code so it takes a void* (if it needs one which your
indirectmalloc does not) and returns a void*, then the problem goes
away. realloc was written the way it was for a reason!
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 13 '06 #2

P: n/a
On Thu, 13 Apr 2006 08:36:09 -0700, ais523 wrote:

ais523 wrote:
I'm trying to write a function that does some realloc-style
modification of a pointer. The function itself works, but I'm having
some problems with the prototype. This is a simple example of the sort
of thing I want to do (not the complete code, that works but is
technically UB).

#include <stdlib.h>

void indirectmalloc(void** ptr, size_t s)
{
*ptr=malloc(s);
return;
}

int main(void)
{
char* a;
int* b;

#if 0
indirectmalloc(&a);
indirectmalloc(&b);

Sorry, that should have been
#endif
indirectmalloc(&a, sizeof *a);
indirectmalloc(&b, sizeof *b);
free(a);
free(b);
return 0;
}

but although all pointers are freely castable to and from void*, not
all pointers-to-pointers are freely castable to and from void**, so
this is UB.
One compiler I use allows &(void*)a, but this is nonstandard. Is there
a portable way of doing this without relying on temporary void*s?
Should I use a #define macro instead? Although there are obviously
easier ways of writing the above code, I'd like to do something like
this (my actual code is more complicated; I'm not posting it because it
works, just invokes UB which happens to not be a problem on my
compiler).


Why not pass the pointer to the function and return the new one
eg
void* indirectmalloc(void* ptr, size_t s)
{
return malloc(s);
}
and call it as in
b = indirectmalloc( b, sizeof *b);

Duncan

Apr 13 '06 #3

P: n/a
In article <pa****************************@this.address>,
Duncan Muirhead <no***@this.address> wrote:
Why not pass the pointer to the function and return the new one
eg
void* indirectmalloc(void* ptr, size_t s)
{
return malloc(s);
}
and call it as in
b = indirectmalloc( b, sizeof *b);


What is the purpose of the first parameter there? You never use it
in indirectmalloc() and never will in that form.

If you drop it from the function definition and the call, then you
essentially just end up with a useless wrapper around malloc() -- one
which would certainly not seem to be in keeping with the spirit of
naming the function "indirectmalloc".

--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
Apr 13 '06 #4

P: n/a
On Thu, 13 Apr 2006 21:21:13 +0000, Walter Roberson wrote:
In article <pa****************************@this.address>,
Duncan Muirhead <no***@this.address> wrote:
Why not pass the pointer to the function and return the new one
eg
void* indirectmalloc(void* ptr, size_t s)
{
return malloc(s);
}
and call it as in
b = indirectmalloc( b, sizeof *b);


What is the purpose of the first parameter there? You never use it
in indirectmalloc() and never will in that form.

If you drop it from the function definition and the call, then you
essentially just end up with a useless wrapper around malloc() -- one
which would certainly not seem to be in keeping with the spirit of
naming the function "indirectmalloc".

My assumption was that in the OP's real code there was other stuff going
on in indirectmalloc -- it was stated that this was not the complete
code.
Apr 14 '06 #5

P: n/a

Flash Gordon wrote:
ais523 wrote:
ais523 wrote:
I'm trying to write a function that does some realloc-style
modification of a pointer. The function itself works, but I'm having
some problems with the prototype. This is a simple example of the sort
of thing I want to do (not the complete code, that works but is
technically UB).
It's in the FAQ http://c-faq.com/ptrs/genericpp.html
Thanks for pointing that out. I have read the FAQ, but obviously not
thoroughly enough, although I was aware of many of the points raised.
If you want to do realloc type stuff, do it the way realloc does it.
#include <stdlib.h>

void indirectmalloc(void** ptr, size_t s)
{
*ptr=malloc(s);
return;
}
Why not return the pointer as malloc does? There is no need in this
example to pass in a pointer to a pointer.
I was trying to make a minimal example of the sort of thing I was
doing. The actual function was designed to expand the amount of memory
allocated in ptr realloc-style, but determining the amount itself, and
with error handling if things went wrong (it would make several
attempts and return the amount it actually managed to allocate).
int main(void)
{
char* a;
int* b;

#if 0
indirectmalloc(&a);
indirectmalloc(&b);

Sorry, that should have been
#endif
indirectmalloc(&a, sizeof *a);
indirectmalloc(&b, sizeof *b);


This is why you should always copy and paste the code you actually
compile from your editor.

I'll try to do that more in future. (I've copied-and-pasted in the
past, but for some reason I didn't this time).
free(a);
free(b);
return 0;
}

but although all pointers are freely castable to and from void*, not
all pointers-to-pointers are freely castable to and from void**, so
this is UB.
One compiler I use allows &(void*)a, but this is nonstandard. Is there
a portable way of doing this without relying on temporary void*s?
No.
Should I use a #define macro instead? Although there are obviously
easier ways of writing the above code, I'd like to do something like
this (my actual code is more complicated; I'm not posting it because it
works, just invokes UB which happens to not be a problem on my
compiler).


Change the code so it takes a void* (if it needs one which your
indirectmalloc does not) and returns a void*, then the problem goes
away. realloc was written the way it was for a reason!


Yes, thinking about it I realise that I can make the pointer the return
value and use an argument to pass back what would have been the return
value.

Apr 16 '06 #6

P: n/a
On 2006-04-16, ais523 <ai****@bham.ac.uk> wrote:

Flash Gordon wrote:
ais523 wrote:
> ais523 wrote:
>
>> I'm trying to write a function that does some realloc-style
>> modification of a pointer. The function itself works, but I'm having
>> some problems with the prototype. This is a simple example of the sort
>> of thing I want to do (not the complete code, that works but is
>> technically UB).
It's in the FAQ http://c-faq.com/ptrs/genericpp.html

Thanks for pointing that out. I have read the FAQ, but obviously not
thoroughly enough, although I was aware of many of the points raised.
If you want to do realloc type stuff, do it the way realloc does it.
>> #include <stdlib.h>
>>
>> void indirectmalloc(void** ptr, size_t s)
>> {
>> *ptr=malloc(s);
>> return;
>> }


Why not return the pointer as malloc does? There is no need in this
example to pass in a pointer to a pointer.

I was trying to make a minimal example of the sort of thing I was
doing. The actual function was designed to expand the amount of memory
allocated in ptr realloc-style, but determining the amount itself, and
with error handling if things went wrong (it would make several
attempts and return the amount it actually managed to allocate).


There is still no need to pointer to pointer. Just pass the already
malloced pointer to your "indirect" function and return NULL for
failure with the stipulation that the caller is responsible for
free'ing the original block.
>> int main(void)
>> {
>> char* a;
>> int* b;
> #if 0
>> indirectmalloc(&a);
>> indirectmalloc(&b);
> Sorry, that should have been
> #endif
> indirectmalloc(&a, sizeof *a);
> indirectmalloc(&b, sizeof *b);


This is why you should always copy and paste the code you actually
compile from your editor.

I'll try to do that more in future. (I've copied-and-pasted in the
past, but for some reason I didn't this time).
>> free(a);
>> free(b);
>> return 0;
>> }
>>
>> but although all pointers are freely castable to and from void*, not
>> all pointers-to-pointers are freely castable to and from void**, so
>> this is UB.
>> One compiler I use allows &(void*)a, but this is nonstandard. Is there
>> a portable way of doing this without relying on temporary void*s?


No.
>> Should I use a #define macro instead? Although there are obviously
>> easier ways of writing the above code, I'd like to do something like
>> this (my actual code is more complicated; I'm not posting it because it
>> works, just invokes UB which happens to not be a problem on my
>> compiler).


Change the code so it takes a void* (if it needs one which your
indirectmalloc does not) and returns a void*, then the problem goes
away. realloc was written the way it was for a reason!


Yes, thinking about it I realise that I can make the pointer the return
value and use an argument to pass back what would have been the return
value.


I dont think you need to do that. Read the manpage for realloc :
although fair enough if you envisage a host of possible return values
from your indirectmalloc function and wish to analyse these later. IMO
one return value is sufficient : the pointer itself.
Apr 16 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.