-2

So, for example i have this function:

char* retCharPtr(void) {
    char data[15] {"Data is here"};
    return data; }

And

char* retCharPtr1(void) {
    char *data = new char[15];
    strcat(data, "Data is here");
    return data; }

Please explain where the data array will be placed if std::cout << retCharPtr1();, and what if std::cout << retCharPtr();?

And in general, where do the values ​​of variables go when functions return their status (int) and it is not stored anywhere. Are these 4 bytes occupied during the full execution of the program?

I need the function to return an array for cout, without the next call delete, and leaks in memory.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • @RemyLebeau retCharPtr() exhibits undefined behavior. | Is it because the function will delete the data array upon completion, and the address being returned points to cleared memory? – Vladyslav Rehan Aug 29 '21 at 19:56
  • And this is a really dangerous undefined behaviour because the likely behaviour chosen by the compiler for `retCharPtr` will look like it worked a lot of the time. A good compiler will warn you not to do this because the time that it visibly *doesn't* work will probably be when you really needed it to work. – user4581301 Aug 29 '21 at 19:57
  • I don't think this is a C++ question (C style coding and asking about implementation defined behaviour). AFAIK the standard doesn't specify where return values are placed. If they are discarded then nowhere. You can go and dig through the generated assembly, to find answers on your given machine/ compiler though – Lala5th Aug 29 '21 at 19:58
  • @VladyslavRehan The stack frame of `retCharPtr` will be destroyed upon returning (with all its contents). Now whether this is implemented as just `leave` in assembly (which will leave the memory there as far as I can tell), or return the memory to the kernel C++ doesn't specify. A compiler can do anything, there and you are accessing memory you shouldn't – Lala5th Aug 29 '21 at 20:01
  • The undefined part is exactly what you are asking. C++ guarantees the memory will continue to contain the expected value until it goes out of scope, but after that, the C++ Standard says nothing other than it's not to be used. [Here's a really good discussion](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – user4581301 Aug 29 '21 at 20:01
  • 2
    The right way to handle this hasn't changed since you asked your [last question](https://stackoverflow.com/questions/68975325/the-function-collects-the-array-and-returns-it-after-ciout-memory-is-still-occu). – StoryTeller - Unslander Monica Aug 29 '21 at 20:03
  • @user4581301 Strictly spoken, `retCharPtr` itself does not expose undefined bahavior. `std::cout << retCharPtr()` does, though. – Peter - Reinstate Monica Aug 29 '21 at 20:18

1 Answers1

3

When a function returns a value, that value exists as a local variable within the caller's current scope (whether the caller uses it or not), and will be destroyed when the variable goes out of scope. So, in your examples, the returned char* pointer (but not the data being pointed at) is destroyed on the ; following the << statement.

In retCharPtr(), the array is stored in automatic memory within the function's scope. When retCharPtr() exits, that memory goes out of scope and is destroyed. Thus retCharPtr() returns a dangling pointer to invalid memory. If the caller tries to read data using that pointer, it will invoke undefined behavior.

In retCharPtr1(), the array is stored in dynamic memory, and will exist until the memory is explicitly delete[]'ed. If the caller does not call delete[] on the returned pointer, the memory allocated by retCharPtr1() will be leaked.

The solution in both cases is to return a std::string instead of a char*. Let the compiler and std::string manage the memory for you.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • As I said above, *calling `retCharPtr()`* is not UB. Outputting the address it returns is not UB. *Reading **from** the address* it returned though is UB. (What I want to say is that the wording "exhibits" is imprecise.) – Peter - Reinstate Monica Aug 29 '21 at 20:24
  • Another thing is that while an in-depth discussion is just beyond the scope of this question, not deleting the dynamic memory does not directly mean it is leaked: Technically it is leaked only after the last pointer to it is lost. Even then good arguments can be made for programs that don't have server characteristics (that is, those which do one job and exit) to simply not bother with freeing and leave it to the OS, unless I'm on an embedded system (where dynamic allocation is limited anyway). – Peter - Reinstate Monica Aug 30 '21 at 00:18