I have a function that returns a string:
const *char getMyPassword()
{
return "mysecretpassword";
}
Well, it worked perfectly, but I discovered that if I would run "strings" on Unix systems it shows up in the list.. not good.
What is the easiest possible way to replace it? The function sits in a library and I want to keep it flexible. I now started mallocing within the function and the string in strings disappeared. However, when would I free it again?
char * getMyPassword()
{
unsigned char arr[] = { 'p', 'a', 's', 's', 'w', 'o', 'r' , 'd', '\0' };
char *return_arr = malloc(sizeof(arr));
strcpy(return_arr, arr);
return return_arr;
}
If I was to malloc before and pass a pointer, then how could I have known the size before as the passwords size is only known within the function?
As a plan B I could pass a huge array, but that seems not very elegant. How should I approach this?
EDIT: I added the strcpy(return_arr, arr). I actually had it in the original code, but forgot it in here.
Strings in C are arrays of char elements, so we can't really return a string - we must return a pointer to the first element of the string. All forms are perfectly valid.
In C, char* means a pointer to a character. Strings are an array of characters eliminated by the null character in C.
using printf() If we want to do a string output in C stored in memory and we want to output it as it is, then we can use the printf() function. This function, like scanf() uses the access specifier %s to output strings. The complete syntax for this method is: printf("%s", char *s);
Since int and char are inter-operable, you can return a char value by typecasting it to int.
Security issues aside, what you are trying to do is dynamically allocate buffer.
You can take 2 approaches.
malloc
inside your function and document it that it returns malloced
result.check
pass, when you pass in a null
buffer, they do not try to allocate it, but instead return the size that is required to hold the structure.Looks to me that you've already implemented approach #1.
For approach #2 use this signature:
int getMyPassword( char* buffer, size_t buff_size, size_t* p_num_copied )
{
unsigned char arr[] = { 'p', 'a', 's', 's', 'w', 'o', 'r' , 'd', '\0' };
if ( buffer == 0 )
{
*p_num_copied = sizeof(arr);
return SUCCESS;
}
if ( buff_size < sizeof(arr) )
{
*p_num_copied = sizeof(arr);
return BUFFER_TOO_SMALL;
}
memcpy( buffer, arr, sizeof(arr) );
*p_num_copied = sizeof( arr );
return SUCCESS;
}
Advantage of method #2 is that the caller, in many cases, may allocate the buffer on stack, especially if you advertise the maximum required buffer size. Another advantage is that memory management is now completely handled by client. In general purpose library you don't want to make a client depending on a particular library memory allocation schema.
IN REPLY TO COMMENT
If you always want to use allocated value in your client code, then this is how I would do this:
char* clientGetPasswordFromLibrary( )
{
// in our day and age it's fine to allocate this much on stack
char buffer[256];
size_t num_copied;
int status = getMyPassword( buffer, sizeof(buffer), &num_copied );
char* ret_val = NULL;
if ( status == BUFFER_TOO_SMALL )
{
ret_val = malloc( num_copied );
if ( ret_val == NULL )
{
return NULL;
}
getMyPassword( ret_val, num_copied, &num_copied );
}
else
{
ret_val = malloc( num_copied );
if ( ret_val == NULL )
{
return NULL;
}
memcpy( ret_val, buffer, num_copied );
}
return ret_val;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With