1

I declared and initialized two char arrays in two ways :

char array_1 [10] = "012345"; 

char* array_2 = Array_Initializer();

The array_initializer is as follows: (I deleted some part that I'm sure irrelevant)

char* Array_Initializer(){
   string return_array = "012345";
   return const_cast<char*> (return_array.c_str());
}

And when I do cout<< array_1<< endl; and cout<< array_2<< endl; Both will output "012345" correctly.

But the problem comes when I pass them into a function that takes char* arg as and argument. The function will only get array_1 correctly, but will get a undefined value when I pass in array_2. Can anyone tell me why?

PS: my sample function looks funny but I only kept what I think relevant :)

  • 1
    [undefined behaviour](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) (x2 if you modify the result) – chris Jul 07 '14 at 03:07
  • Update: if I do strcpy(array_2, Array_Initializer()); this time array_2 will be recognized correctly when passed to the function as a char* argument. Can someone please tell me why? :/ – user3321813 Jul 07 '14 at 03:08
  • 1
    @user3321813 It's still undefined behavior, but you are a lot more likely to have not overwritten the memory the local variable was in immediately after you return than later when you were accessing it from a function. – IllusiveBrian Jul 07 '14 at 03:12
  • @Namfuak do you have any suggestion on how to do if I want to use a initializer function to determine the array? – user3321813 Jul 07 '14 at 03:15
  • 1
    @user3321813, Return a `std::string`. – chris Jul 07 '14 at 03:15
  • Please be aware that C and C++ are two different languages. It is only appropriate to have both tags in your question if it involves the two languages. If you are unsure which language you are using, stop right there and make a decision. – n. m. could be an AI Jul 07 '14 at 03:15
  • @n.m. yes you are right, I just deleted the C tag. Thx for reminding – user3321813 Jul 07 '14 at 03:19
  • @user3321813 If you are not able to use a `std::string` as chris suggested (if you are in C++ I would really recommend this), you can use `malloc` to reserve the memory for your string and expect the function caller to use `free` later, but the better solution is to put a `const char*` and `size_t` (`const char*` being destination, `size_t` being the amount of allocated memory for `const char*`) as function parameters and fill the `const char*` with up to `size_t` characters. – IllusiveBrian Jul 07 '14 at 03:20
  • And a final note, you should not be using pointers and char arrays (C strings) in C++ code much, except to interoperate with legacy code. `std::string` should be your default choice. – n. m. could be an AI Jul 07 '14 at 03:24
  • @Namfuak Reaaly appreciate the elaborated explanation! Sorry it is my bad that I tagged both C and C++. I'm using C++ so using string seems work fine for me as of right now. But also glad that I just learned alot about C from you. – user3321813 Jul 07 '14 at 03:28
  • `std::string` is even great for legacy code in C++11. `void foo(const char *); foo(s.c_str()); void bar(char *); bar(&s[0]);` – chris Jul 07 '14 at 03:28
  • Did someone just convert the code block for me ?? THANKS! – user3321813 Jul 07 '14 at 03:39

1 Answers1

2

When you do a "return const_cast (return_array.c_str());" you are returning a pointer to memory that probably goes away, so you aren't guaranteed to be pointing to valid data after the return. It might be helpful to realize that the string class is copying data into itself (or memory that it manages) and you are returning a pointer to that memory, but when the string goes out of scope, it returns that memory. It could happen that the memory still contains the "012345" value until it gets overwritten by something else, so it might appear to work, but its not a good idea. If on the other hand, you leaked the string object, so did a new on it and didn't delete it, I suspect this would "work" (but then leak the string object, which is usually a bad idea).

The "const_cast" does nothing to guarantee that the data that is pointed to still remains valid.

David Neiss
  • 8,161
  • 2
  • 20
  • 21
  • `const_cast` ensures that the type is *not* constant. – quant Jul 07 '14 at 03:13
  • So how should I return the char array using the initializer function? Should I simply just pass the array pointer into it and modify it instead of returning a new array at all ? – user3321813 Jul 07 '14 at 03:13
  • @user3321813 : I think you can get around by using "static" char[] instead inside the function. static data will be preserved. But it is not a good idea though. other function call will change the data. – someone_ smiley Jul 07 '14 at 03:17
  • 1
    user332... Can you just convert over everything to use std::strings, it will make your life easier and you wont have to deal with these kinds of issues and the string class lets you do all kinds of operations on your data. – David Neiss Jul 07 '14 at 03:23