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

Design question dealing with char* function

P: n/a
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

Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
fernandez....@gmail.com wrote:
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

Nov 15 '05 #2

P: n/a
On 28 Jul 2005 08:50:05 -0700, fe***********@gmail.com wrote in
comp.lang.c:
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.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #3

P: n/a

fe***********@gmail.com wrote:
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;
}

Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.