3

I learned that when I initialize an array of chars it's just like initializing a pointer to chars. But, if that is the situation, why does the following code output strange characters?

char* returnMe()
{
    char text[] = "Will I live forever?";
    return text;
}

While the following code:

char* returnMe()
{
    char* text = "Will I live forever?";
    return text;
}

outputs:

Will I live forever?

What exactly are the differences between these two initializations? They both act like pointers, so if I do:

puts(X); //puts get char* as a parameter in it.

It will work for both cases (When I haven't gone out of scope yet.)

jaggedSpire
  • 4,423
  • 2
  • 26
  • 52
wrg wfg
  • 77
  • 6
  • Related: http://stackoverflow.com/questions/30533439/string-literals-vs-array-of-char-when-initializing-a-pointer – Eugene Sh. Feb 15 '17 at 21:59
  • You aren't returning arrays in either case. You're returning a pointer to the first element of an array. This is important if the array ceases to exist. – juanchopanza Feb 15 '17 at 22:00
  • 2
    btw in c++ you can avoid all that headace by using `std::string` – 463035818_is_not_an_ai Feb 15 '17 at 22:00
  • Refer this. http://stackoverflow.com/questions/1335786/c-differences-between-char-pointer-and-array – Dineshkumar Feb 15 '17 at 22:02
  • Your code will cause a UB: returning a local variable: `return text` "text[]". – Raindrop7 Feb 15 '17 at 22:07
  • 2
    _sigh_ C is not C++ is not C. Don't spam tags! And "CPP" is the C **P**re**P**rocessor, not C++! – too honest for this site Feb 15 '17 at 22:11
  • And you apparently learned something wrong. If an array was a pointer, it would be called "pointer", not "array" (and vice versa). – too honest for this site Feb 15 '17 at 22:13
  • 1
    @Olaf usually I fully support your C is not C++ crusade, but even SO lists cpp as synonym for C++ (though in lowercase) – 463035818_is_not_an_ai Feb 15 '17 at 22:20
  • 1
    The `char*` should rather be `const char*` for reasons mentioned [here](http://stackoverflow.com/a/8795589/1460794). – wally Feb 15 '17 at 22:33
  • @tobi303: try `cpp` on your console. (and that is not related to the C is not C++ policy, a both use the CPP.) Anyway, I removed the CPP, as the language should not be in the title anyway. That's what tags are for. – too honest for this site Feb 15 '17 at 22:33
  • 1
    "I learned that when I initialize an array of chars it's just like initializing a pointer to chars" - this is wrong , whatever source you "learned" that from you should now regard as being a bad source. – M.M Feb 16 '17 at 00:14
  • `char* text = "Will I live forever?";` has not been valid C++ since 2010, it's invalid in C++11, for good reasons. It should be `const char* text = "Will I live forever?";` – Jonathan Wakely Feb 16 '17 at 00:35

1 Answers1

10

The function containing this:

 char text[] = "Will I live forever?";

returns a pointer to a local variable called text, which contains the string "Will I live forever?". As with all local variables, that variable evaporates after the function returns, and so you are off in undefined behaviour land if you try to access it.

The function containing this:

 char* text = "Will I live forever?";

returns a pointer to some magic place in memory (but not a local variable) containing the string, which persists for the program's execution, so using that pointer is not undefined behaviour.

  • So long text to just say 'Memory is allocated: 1. On the stack. 2. On the read only section in the binary.' That explains everything. – 0andriy Feb 15 '17 at 22:04
  • @tobi303 it returns "copy" of local variable. (Because ABI defines returned code to be %r1 IIRC, thus anything which fits register can be returned in such way) – 0andriy Feb 15 '17 at 22:04
  • @tobi303, shallow copy, yes. Pointer fits register. That's all what you get for `return text;` case. – 0andriy Feb 15 '17 at 22:06
  • 1
    This has nothing to do with what can fit in a register. –  Feb 15 '17 at 22:13
  • 2
    I never completely understood that array vs pointer stuff, I really learned something from this answer :) upvoted (and removed some noisy comments) – 463035818_is_not_an_ai Feb 15 '17 at 22:17
  • @NeilButterworth, how come? On low level it's exactly what ABI defines. On next level is some other standards and agreements involved (such as C standard). UB in this case is so obvious. – 0andriy Feb 15 '17 at 22:17
  • @0 There is no C++ ABI. There is nothing in C++ that requires return values be passed in registers, or suggests different semantics if they are passed that way. On the contrary, C++ (and C) programs must behave in the same way however function and return values are implemented.. –  Feb 15 '17 at 22:19
  • @NeilButterworth, Again, (most of the people here by some unknown reason afraid of magic ABI abbreviation) the C standard is on **upper** level than ABI. ABI is defined **without** referring to **any** programming language except direct CPU instructions. ABI is written for **CPU**, not for the PL. – 0andriy Feb 15 '17 at 22:21
  • @0 Sorry, you either don't know what you are talking about, you can't express yourself in English, or both. –  Feb 15 '17 at 22:22
  • @NeilButterworth, okay, English is not my native, indeed, but you chose way to talk offtopic. Just google for ABI x86_64, or ABI for ARM. – 0andriy Feb 15 '17 at 22:24
  • @0andriy afaik one major reason to write code in c++ is to not care about the details of the cpu, like registers for example – 463035818_is_not_an_ai Feb 15 '17 at 22:27
  • @tobi303, correct. I oppose the *This has nothing to do with what can fit in a register.* It definitely has. – 0andriy Feb 15 '17 at 22:28
  • nothing to do with this question, he would have the same problem if he returned huge struct with pointers to local variables, for sure wont fit in registers, for sure still crashes – pm100 Feb 15 '17 at 22:42
  • 1
    @0andriy some systems have neither a stack, nor a read-only section in the binary. The question can, and IMO should , be answered without reference to specific system details – M.M Feb 16 '17 at 00:15