Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return char* from function

Tags:

Below are 3 functions. main() prints out as expected. Now, in mycharstack() the string is stored on stack I guess, so as "ch" goes out of scope, it should not be able to return the string. How does it work correctly? I guess the string stored in mychar() is also on stack. Is it supposed to work correctly? I guess there are other errors in the code and memory leaks, please let me know if any. I could do these cleaner & easier with std::string. But I want to understand what's going on with char*.

#include <iostream> using namespace std;  char* mychar() {     return "Hello"; }  char* mycharstack() {     char* ch = "Hello Stack";     return ch; }  char* mycharheap() {     char* ch = new char;     ch = "Hello Heap";     return ch; }  int main() {     cout << "mychar() = " << mychar() << endl;     cout << "mycharstack() = " << mycharstack() << endl;     cout << "mycharheap() = " << mycharheap() << endl;      system("PAUSE");     return 0; } 
like image 848
ontherocks Avatar asked Jan 17 '13 12:01

ontherocks


People also ask

What does a char * function return?

This is because the function does not return a single character. Instead it returns an address which POINTS to a character (hence the name pointer), and it is denoted by a * .

How do I return a char pointer?

One solution is to allocate the appropriate amount of memory in the main function, and pass the pointer to the memory to the helper function. Show activity on this post. you shouldn't return data that sits on automatic storage, when you return it goes out of scope. scope and storage duration are two different beasts.

Can function return char in C?

Can we return a char in the main function in C? Yes we can, but it will be technically unfeasible. Usually, main() is the entry point of a C program, and when the control reaches to the end of main(), the program terminates.


2 Answers

In C++, the string handling is different from, for example, pascal.

char* mycharheap() {     char* ch = new char;     ch = "Hello Heap";     return ch; } 

This does following:

  1. char* ch = new char; creates memory for ONE character, and assigns it to variable ch
  2. ch = "Hello Heap"; assigns to variable ch pointer to readonly memory, which contains bytes "Hello Heap\0". Also, the original content of variable ch is lost, resulting in memory leak.
  3. return ch; returns the pointer stored to variable ch.

What you probably wanted is

char* mycharheap() {     char* ch = new char[11] /* 11 = len of Hello Heap + 1 char for \0*/;     strcpy(ch, "Hello Heap");     return ch; } 

Note the strcpy -> you've got memory in ch, that has space for 11 chars, and you are filling it by string from read-only portion of memory.

There will be a leak in this case. You will need to delete the memory after writing, like:

char* tempFromHeap = mycharheap(); cout << "mycharheap() = " << tempFromHeap << endl; delete[] tempFromHeap; 

However, I highly don't recommend doing this (allocating memory in callee and deleting in caller). For this situations, there are, for example, STL std::string, another common and more reasonable approach is allocating in caller, passing to callee, which 'fills' the memory with result, and deallocating in caller again.

What will result in undefined behavior is following:

char* mycharstack() {     char[] ch = "Hello Heap"; /* this is a shortcut for char[11] ch; ch[0] = 'H', ch[1] = 'e', ...... */     return ch; } 

This will create array on stack with bytes "Hello Heap\0", and then tries to return pointer to first byte of that array (which can, in calling function, point to anything)

like image 182
nothrow Avatar answered Jan 04 '23 05:01

nothrow


in mycharstack() the string is stored on stack I guess, so as "ch" goes out of scope, it should not be able to return the string. How does it work correctly?

A string literal refers to an array that lives in static memory. I hope you are aware of the three memory areas: automatic memory (aka stack), free store (aka heap) and static memory. That thing on the stack is just a pointer variable and you return the value of the pointer (the address it stores) by value. So everything is fine except for the fact that you should have used const char* as pointer type because you are not allowed to modify the array a string literal refers to.

I guess the string stored in mychar() is also on stack.

The string (the character array) is stored in static memory. char* is just a pointer type you can use to pass addresses around. const is also missing.

I guess there are other errors in the code and memory leaks, please let me know if any.

The leak is in your third function. You allocate memory for just one character on the heap and store its address into the variable called ch. With the following assignment you overwrite this address with the address of a string literal. So, you're leaking memory.

You seem to be thinking of char* as type for string variables. But it is not. It's the type for a pointer to a character or character sequence. The pointer and the string it might point to are two seperate things. What you probably should be using here is std::string instead.

like image 42
sellibitze Avatar answered Jan 04 '23 06:01

sellibitze