×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

return a string from a function
5

return a string from a function

return a string from a function

(OP)
Hello,

I have a short example of a C library that I have coded below along with the header. I am calling this function from a C++ client app.

Some of the warning I get are as follows. This normally gives me a segmentation stack run time error. So I guess some about memory not been allocated being assigned to null address.

warning: return from incompatible pointer type
warning: function returns address of local variable

I have tried many different ways to do this. As you can see from my commenting out pieces of code.

However, I can return pointer without any problems. However, my code needs to return a string array. i.e.     char msgTest[] = "Hello how are you";

Can any one offer any advice on this?

Many thanks for any suggestions.

CODE

//C library code
//Header cHeader.h
#ifdef __cplusplus
extern "C"
{
#endif
    char* returnMessage(char *message);
#ifdef __cplusplus
}
#endif

//Implementation cDriver.c
char* returnMessage(char *message)
{
    printf("Message: %s\n", message);
    
    char *msg = NULL;
//     //msg = message;
//     printf("msg = message: %s\n", msg);
//     //strcpy(msg, message);
//     printf("strcpy(msg, message): %s\n", msg);
    
    char msgTest[] = "Hello how are you";
    strcpy(msg, msgTest);
    return &msgTest;
}

And the C++ code for calling the above function.

CODE

int main(int argc, char** argv)
{
    char *ptrTest = NULL;
    char test[] = "Hello";
    ptrTest = test;
    char *ptrRtn = NULL;

    ptrRtn = returnMessage(ptrTest);
    cout << "PtrRtn: " << ptrRtn << endl;

        return 0;
}

RE: return a string from a function

2

CODE

char msgTest[] = "Hello how are you";
This is a local variable allocated on the stack, so if you return a pointer to it, you're returning a pointer to a variable that no longer exists and could be overwritten at any moment.
If you want to return a string from a function, you either need to make the variable static which means it doesn't get deleted once the function ends (although then your function isn't thread-safe); or you need to allocate memory for the new string (using malloc() ) and copy the string into it (using strcpy() or strncpy() ).
If you return a pointer to memory you allocated in a function, you need to remember to free that memory later, so it might be better to pass a pointer into the function along with the size it can store, then you don't have to allocate the memory inside the function.

CODE

#include <stdio.h>
#include <string.h>
#define STR_SIZE 80

void GetString( char* strOut, unsigned int strSize )
{
   strncpy( strOut, "Hello World", strSize );
}

int main()
{
   char buf[STR_SIZE + 1];

   GetString( buf, STR_SIZE );
   printf( "%s", buf );
   return 0;
}

RE: return a string from a function

(OP)
Hello,

thanks for the reply,

i have used malloc, which worked. Howerver, At which point do I free the memory? As I can't do it after I have returned, or after I have copied the contents?

CODE

char* returnMessage(char *message)
{
    printf("Message: %s\n", message);
    
    char *msg = (char *) malloc(sizeof(char));
    
    char msgTest[] = "Hello how are you";
    
    strncpy(msg, msgTest, sizeof(msgTest));
    
        //when to free the memory that has been allocated.
    return msg;
}

I have noticed I get a stack dump.

Many thanks,

RE: return a string from a function

2
Minor bug in your memory allocation.

CODE

char* returnMessage(char *message)
{
    printf("Message: %s\n", message);
    char msgTest[] = "Hello how are you";
    
    // Allocate the space required: not 1 character
    char *msg = (char *) malloc(strlen (msgTest) + 1);
        
    strncpy(msg, msgTest, sizeof(msgTest));
    
        //when to free the memory that has been allocated.
    return msg;
}
You could also use strdup

CODE

char* returnMessage(char *message)
{
    printf("Message: %s\n", message);
    char msgTest[] = "Hello how are you";
    
        //when to free the memory that has been allocated.
    return strdup (msgTest);
}
You free it when you no longer need it.

Warning about using sizeof and strlen.  Sizeof is compile time, strlen is runtime.  If you are using pointers, sizeof will always return the same result.  If you're passing strings into routines, it is better to use strlen.

CODE

char str1[] = "seven";
char* str2  = "seven";
printf ("sizeof str1=%d str2=%d\n", sizeof(str1), sizeof(str2));
printf ("strlen str1=%d str2=%d\n", strlen(str1), strlen(str2));
 

RE: return a string from a function

(OP)
Hello,

Thanks for your help. I have used the code below:

CODE

char* returnMessage(char *message)
{
    printf("Message: %s\n", message);
    
    char msgTest[] = "Hello how are you";

    char *msg = (char *) malloc(strlen(msgTest) + 1);

    strncpy(msg, msgTest, sizeof(msgTest));
    
    return msg;
}

What is the purpose of adding 1 to the string length. Is this for safety?

Why would having a static variable be not thread safe?

Just a final question about freeing memory that has been allocated. As the function returnMessage allocated memory, how can I free that in the calling function, as it will not have scope?

Many thanks,

 

RE: return a string from a function

(OP)
Hello,

When freeing memory I have freed the memory in the calling function. As below.

CODE

int main(int argc, char** argv)
{
    char *ptrTest = NULL;
    char test[] = "Hello";
    ptrTest = test;
    char *ptrRtn = NULL;

    ptrRtn = returnMessage(ptrTest);
    cout << "PtrRtn: " << ptrRtn << endl;
        
        free(ptrRtn); //Freeing the memory that was allocated in the returnMessage function.
        return 0;
}
Any corrections please advise,

Thanks,

RE: return a string from a function

Quote (rokUK2):

What is the purpose of adding 1 to the string length. Is this for safety?

Why would having a static variable be not thread safe?
All valid C strings end with a NUL character (i.e. '\0'), which isn't included in the length reported by strlen()...  Without the NUL character, there's no way for something like puts() or printf() to know where the string ends.  So you need to add 1 character for the '\0'.

As for static variables not being thread-safe, consider the gmtime() function which converts a time_t value into a tm* struct.  Since the tm* pointer it returns points to a static tm struct inside the function, that data gets overwritten the next time the function is called.  And static data is shared between threads.
So thread1 calls gmtime() and starts reading the tm* struct it returns, then thread2 calls gmtime() and gets a tm* struct which has changed some of the data in that struct.  So now when thread1 continues reading its tm* struct, it's reading the data that thread2 changed.

RE: return a string from a function

As far I know you allready got an solution.
But I do not like to allocate memory where someone has to free somewhere!
Remember, in ANSI C a function can return against normal data types (like int, chr ...) also return abstract data type (what means a structur and typedef). An that works so easy. You may define a structur fill it out and return it. The structure will be put to sthe stack an copied to the assigned structure.
Look at my code snipe:


/* Code */
struct a { char str[200]; int i };

struct a func1() {
  struct a func_a;
  strcpy(func_a.str,"my string return");
  func_a.i = 99;
  return func_a;
};  

main() {
  struct a main_a;
  strcpy(main_a.str,"my string return");
  main_a.i = 99;
  printf("before func1 call str=%s i=%d\n",
          main_a.str,main_a.i);
  main_a = func1();
  printf("after func1 call str=%s i=%d\n",
          main_a.str,main_a.i);
  exit(0);
};
 

RE: return a string from a function

Two remarks on your code :
1) It only works when the length of the strings are less than 200, when you don't know the length it may be risky...
2) It takes a long time when copying all the bytes at the return of the function, it is preferable to copy only an address, and we get back to the code of xwb.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close