Design question dealing with char* function

F

fernandez.dan

My question is about if I should return char* or have a char* as an
argument. My basic premise for this function is to return a char*
buffer and the size of the buffer to the caller. I know that each of
the following works but Stylistic which would be the better approach.

Here are my two examples:

char* GetBuffer(long* size);

or


void GetBuffer(char* buff, long* size);


Thanks


Danny
 
D

David Resnick

My question is about if I should return char* or have a char* as an
argument. My basic premise for this function is to return a char*
buffer and the size of the buffer to the caller. I know that each of
the following works but Stylistic which would be the better approach.

Here are my two examples:

char* GetBuffer(long* size);

or


void GetBuffer(char* buff, long* size);

They are not the same, the second doesn't let you return
the buffer. Perhaps you meant "char ** buff"?

Once you are returning multiple things, my inclination would
be more like this:

int GetBuffer(char **buf_out, size_t *buf_size_out)

Where the return int is for status reporting,
such as couldn't allocate a buffer/etc. I tend to name
parameters used to return values with _out, just my style,
as it is sometimes difficult to tell at a glance
in the header file which parameters are being used for
input to the function and which for output.

A reasonable alternative, leaning more towards use of
"objects", is to return a structure containing both the
buffer and its size. Some overhead for the struct, but
then you have the buffer and its size in a nice package
you can pass around...

But this is all style, you'll get lots of opinions...

-David
 
J

Jack Klein

My question is about if I should return char* or have a char* as an
argument. My basic premise for this function is to return a char*
buffer and the size of the buffer to the caller. I know that each of
the following works but Stylistic which would be the better approach.

Here are my two examples:

char* GetBuffer(long* size);

or


void GetBuffer(char* buff, long* size);


Thanks


Danny

Don't use long for sizes. That's not what it is for, and it is quite
possible that on the 64-bit systems that are going to become common
soon objects can be larger than an unsigned long, let alone a signed
one.

Use size_t for the size of things, that is what it is for. There will
never be an implementation where an object will exist with a size too
large to fit into a size_t.
 
J

John Bode

My question is about if I should return char* or have a char* as an
argument. My basic premise for this function is to return a char*
buffer and the size of the buffer to the caller. I know that each of
the following works but Stylistic which would be the better approach.

A couple of questions:

1. The caller doesn't know how big of a buffer it's requesting?

2. What determines the buffer size?
Here are my two examples:

char* GetBuffer(long* size);

or


void GetBuffer(char* buff, long* size);


Thanks


Danny

My personal preference for writing allocators is to have the thing
being allocated as the return value: i.e.,

thing *p = newThing(/* any necessary inputs here*/);

To indicate an error, I'll return NULL, and (usually) provide a second
function to get information on the cause of the error.

char *buf = newName(10);
if (!buf)
{
int errcode = newNameErr();
switch(errcode)
{
...
}
}

I *typically* do not use output parameters in the allocator function; I
try to keep those kinds of things single-valued if I can, but sometimes
an output parameter is necessary. If the multiple outputs are
*logically* connected (I'd consider a buffer and its length to be
logically connected), then I'll create a new struct type and return a
new instance of it:

typedef nameBuf {
char *buffer;
size_t length;
} nameBuf_t;

nameBuf_t *newName()
{
nameBuf_t *newBuf = malloc(sizeof *newBuf);
if (newBuf)
{
size_t newLength = ... /* however buffer length is determined
*/
newBuf->buffer = malloc(sizeof *(newBuf->buffer) * newLength);
if (newBuf->buffer)
{
newBuf->length = newLength;
/* initialize buffer contents if necessary */
}
else
{
newNameErrorSet(MALLOC_FAILURE, newLength);
free(newBuf);
newBuf = NULL;
}
}

return newBuf;
}

int main(void)
{
nameBuf_t *name;

name = newName();
if (!name)
{
fprintf(stderr, "name allocation failed: %s\n",
newNameError());
...
}
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top