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;
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.
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.
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.
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.
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...
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.