How to handle pointers inside of a function ?

G

George Marshall

Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ? Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

Thanks.

/* Example function */
int str_do_something ( const char *src, char *dest)
{
if (src == NULL)
return 0;

do_something_to_str(src);

/* What is good practice to do with the dest pointer here ?*/
/* free before malloc ? realloc ? check if != NULL ? */
dest = malloc (strlen(src));
if (dest == NULL)
return -1;
strcpy (dest,src);
return 0;
}
 
A

Allan Bruce

George Marshall said:
Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ? Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

Thanks.

/* Example function */
int str_do_something ( const char *src, char *dest)
{
if (src == NULL)
return 0;

do_something_to_str(src);

/* What is good practice to do with the dest pointer here ?*/
/* free before malloc ? realloc ? check if != NULL ? */
dest = malloc (strlen(src));
if (dest == NULL)
return -1;
strcpy (dest,src);
return 0;
}

I usually design the function to take a garbage pointer in and initialise it
within the function.
In this case, I would use the return value of 0 for an error (either, the
src pointer is garbage or the memory allocation fails), and would return the
result from strcpy or perhaps the amount of memory allocated to the new
pointer if you are doing some other function.
HTH
Allan
 
T

T.M. Sommers

George said:
Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ? Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

It's up to you; just make sure you document it so that users of your
function (including you next week) know how it works. For example,
users need to know that the function as implemented below allocates
memory, so that they, the users, have to free it later.
/* Example function */
int str_do_something ( const char *src, char *dest)

int str_do_something ( const char *src, char **dest)

Since you are modifying dest, you need to pass in a pointer to it. Or
you could have the function return a char *.
{
if (src == NULL)
return 0;

do_something_to_str(src);

/* What is good practice to do with the dest pointer here ?*/
/* free before malloc ? realloc ? check if != NULL ? */
dest = malloc (strlen(src));

*dest = malloc (strlen(src) + 1);

Don't forget the terminating NULL.
if (dest == NULL)

if (*dest == NULL)
return -1;
strcpy (dest,src);

strcpy (*dest,src);
return 0;
}

It also might be better to do_something to the new string, not the
original. It is generally best to have a function do one thing
(return modified copy of string) rather than two (modify string,
return copy of modified string).

char *str_do_something ( const char *src )
{
char *dest = NULL;
if ( src ) {
if ( (*dest = malloc (strlen(src) + 1)) ) {
strcpy(*dest, src);
do_something_to_str(dest);
}
}
return dest;
}
 
A

Allan Bruce

Allan Bruce said:
I usually design the function to take a garbage pointer in and initialise it
within the function.
In this case, I would use the return value of 0 for an error (either, the
src pointer is garbage or the memory allocation fails), and would return the
result from strcpy or perhaps the amount of memory allocated to the new
pointer if you are doing some other function.
HTH
Allan

Since I was bored, I have written a sample program that I would use for
doing what you wish. Ignore it, use it or rape it, up to you ;-)




#include "stdlib.h"
#include "stdio.h"
#include "string.h"

int strSomething(const char *xiSrc, char **xoDst);

int main (void)
{
char *src = "Some Text Here";
char *dst = NULL;
int memAllocd;

if ((memAllocd = strSomething(src, &dst)) == 0)
printf("Error Allocating Memory\n");
else
printf("Memory Allocated: %d Bytes\nContents: %s\n", memAllocd, dst);

/* Free the memory allocated */
if (dst)
free(dst);

return 0;
}

/************************************************
* Name: strSomething
* Desription: xxx
************************************************/
int strSomething(const char *xiSrc, char **xoDst)
{
/* I use xiXXX for pointers that are valid coming into a function
and should not be altered. xoXXX for pointers which are garbage
and should be allocated and alterd. */
int lMemAllocd;

if (xiSrc == NULL)
return 0;

/* Allocate enough memory for the string and NULL terminator */
if ((*xoDst = malloc(lMemAllocd = strlen(xiSrc)+1)) == NULL)
return 0;

/* Do something to the string */
strcpy(*xoDst, xiSrc);

return lMemAllocd;
}
 
I

Irrwahn Grausewitz

George Marshall said:
Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ?

If you are writing to memory through a pointer you should /always/ check
it's != NULL (unless you already know for sure it's a valid pointer).
Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

If you do so in the example you provide below, the result of both
strategies is nothing more but a memory leak, as the caller of the
function will never be able to retrieve the new pointer.

Additionally, (re)allocation will only be possible if dest is not
declared as an array.
Thanks.

/* Example function */
int str_do_something ( const char *src, char *dest)
{
if (src == NULL)
return 0;

do_something_to_str(src);

Ouch. You _do_something_to_a_const_char_*_ here, which is presumably not
what the caller of this function expects to happen.
/* What is good practice to do with the dest pointer here ?*/
/* free before malloc ? realloc ? check if != NULL ? */
dest = malloc (strlen(src));

Severe error if dest was an array originally!
if (dest == NULL)
return -1;
strcpy (dest,src);

Booom (read: undefined behaviour)!
You did not allocate enough memory to hold the copy of src.
return 0;
}

How do you expect anybody to access the memory dest currently points to,
once you lost the only reference to it after your function returned?

Common practice is to let the caller take care of the memory allocation,
check for NULL pointers, eventually let the caller supply an additional
size argument (like in strncpy), and return a pointer to the resulting
string, like in the following (admittedly silly) example:

/*--------------8<----------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *do_something_to( char *s )
{
char *p;

for ( p = s; *p; p++ )
if ( *p == 'u' )
*p = 'x';

return s;
}

char *str_do_something( char *dest, const char *src )
{
if ( dest == NULL || src == NULL )
return NULL;

strcpy( dest, src );

return do_something_to( dest );
}

int main( void )
{
char s[10] = "useless";
char t[10];

if ( str_do_something( t, s ) == NULL )
return EXIT_FAILURE;

printf( "s: %s\nt: %s\n", s, t );
return EXIT_SUCCESS;
}

/*--------------8<----------------------------*/

Another possibility is to take only src as argument, allocate dest in
the function and return it to the caller, much like the (non-standard)
strdup function available on many implementations.

HTH

Regards
 
E

Ed Morton

George said:
Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ? Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

Just document the interface as requiring *dest to be NULL and test for
that. Keep it simple. Assuming you want to keep *dest as a parameter,
I'd write your function as:

int str_do_something ( const char *src, char **dest)
{
int ret = 0;
if (dest == NULL) {
ret = -1;
} else if (*dest != NULL) {
ret = -2;
} else if (src != NULL) {
*dest = malloc (strlen(src) + 1);
if (*dest == NULL) {
ret = -3;
} else {
(void)strcpy (*dest,src);
do_something_to_str(*dest);
}
}
return ret;
}

Regards,

Ed.
 
N

Nick Austin

Hi all, my question is what should I do with a pointer
to be used inside a function ?

The following function should take a pointer to a null
terminated array of chars, do something with it, and
write to the other pointer (*dest).

Should I check if the *dest pointer is NULL or not
before writing to it ? Should I realloc it before
I write to it ? Should I free it if != NULL and
then allocate it again ?

Thanks.

/* Example function */
int str_do_something ( const char *src, char *dest)
{
if (src == NULL)
return 0;

do_something_to_str(src);

/* What is good practice to do with the dest pointer here ?*/
/* free before malloc ? realloc ? check if != NULL ? */
dest = malloc (strlen(src));
if (dest == NULL)
return -1;
strcpy (dest,src);
return 0;
}

Unless you need to distinguish the reason for failure, i'd make
the function return a pointer instead:

char *str_do_something (const char *src)
{
char *dest = NULL;

if (src)
{
do_something_to_str (src);

dest = malloc (strlen (src));
if (dest)
strcpy (dest,src);
}

return dest;
}

Nick.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top