Since I can't return a local variable, what's the best way to return a string from a C or C++ function?

前端 未结 8 2082
失恋的感觉
失恋的感觉 2020-11-30 05:19

As a follow-up to this question:

From what I\'ve seen, this should work as expected:

void greet(){
  char c[] = \"Hello\";
  greetWith(c);
  return;
         


        
相关标签:
8条回答
  • 2020-11-30 05:36

    Returning malloc'd memory from a function as suggested by several of the other responses is just asking for a memory leak. The caller would have to know you malloc'd it and then call free. If they happened to call delete on it, the results are undefined (although probably okay).

    It would be better to force the caller to provide the memory for you and then copy your string into it. This way the caller is on notice that he/she needs to clean up.

    0 讨论(0)
  • 2020-11-30 05:37

    Depends if the embedded environment has a heap or not, if so, you should malloc as follows:

    char* greet()
    {
      char* ret = malloc(6 * sizeof(char)); // technically " * sizeof(char)" isn't needed since it is 1 by definition
      strcpy(ret,"hello");
      return ret;
    }
    

    Note that you should later call free() to clean up. If you don't have access to dynamic allocation, you will need to make it a global, or a variable on the stack, but further up the call stack.

    0 讨论(0)
  • 2020-11-30 05:39

    You can use either of these:

    char const* getIt() {
        return "hello";
    }
    
    char * getIt() {
        static char thing[] = "hello";
        return thing;
    }
    
    char * getIt() {
        char str[] = "hello";
        char * thing = new char[sizeof str];
        std::strcpy(thing, str);
        return thing;
    }
    
    shared_array<char> getIt() {
        char str[] = "hello";
        shared_array<char> thing(new char[sizeof str]);
        std::strcpy(thing.get(), str);
        return thing;
    }
    

    The first requires you to not write to the returned string, but also is the simplest you can get. The last uses shared_array which automatically can clean up memory if the reference to the memory is lost (the last shared_array to it goes out of scope). The last and second last must be used if you require a new string everytime you call the function.

    0 讨论(0)
  • 2020-11-30 05:41

    If you are using C++, then you may want to consider using std::string to return strings from your second function:

    std::string greet() {
        char c[] = "Hello";
        return std::string(c); // note the use of the constructor call is redundant here
    }
    

    Or, in a single threaded environment you can do:

    char *greet() {
        static char c[] = "Hello";
        return c;
    }
    

    The static here allocates space in the global memory area, which never disappears. This static method is fraught with peril, though.

    0 讨论(0)
  • 2020-11-30 05:43

    From what I've read the safest option is to make the caller responsible for allocating memory to hold the string. You must also check if the buffer is large enough to hold your string:

    char *greet(char *buf, int size) {
         char *str = "Hello!"
         if (strlen(str) + 1 > size) { // Remember the terminal null!
              return NULL;
         } 
         strcpy(buf, str);
         return buf;
    }
    
    void do_greet() {
        char buf[SIZE];
        if (greet(buf, SIZE) == NULL) {
            printf("Stupid C");
         } 
         else {} // Greeted!
    }
    

    A ton of work for a simple task... but there's C for you :-) Oops! Guess I was beaten by random_hacker...

    0 讨论(0)
  • 2020-11-30 05:46

    If you need to do this in C++, using std::string as suggested by Greg Hewgill is definitely the most simple and maintainable strategy.

    If you are using C, you might consider returning a pointer to space that has been dynamically allocated with malloc() as suggested by Jesse Pepper; but another way that can avoid dynamic allocation is to have greet() take a char * parameter and write its output there:

    void greet(char *buf, int size) {
        char c[] = "Hello";
    
        if (strlen(c) + 1 > size) {
            printf("Buffer size too small!");
            exit(1);
        }
    
        strcpy(buf, c);
    }
    

    The size parameter is there for safety's sake, to help prevent buffer overruns. If you knew exactly how long the string was going to be, it would not be necessary.

    0 讨论(0)
提交回复
热议问题