-2

I have a class: .h

class test {
public:
    int Length;
    char* Name;
    int* ARR;
    test(int l, char* n, int* a);
    test();
};

.cpp

test::test(int l, char* n, int* a){
    Length=l;
    Name=n;
    ARR=a;
}

And main.cpp

#include<iostream>
void InAFunc(test *kio) {
    int foo[3] = { 1,2,3 };
    *kio = test(7, "Hello!", foo);
}
int main() {
    test mmk;
    InAFunc(&mmk);
    std::cout << mmk.Name << mmk.ARR[1];
}

As I know, I may got an exception on ARR, because variable foo has been release at the end of function InAFunc. I need to do new or malloc to Arr to avoid it. My question is why "Hello!" is safe? I code a lot like this in the past but never wrong. Why leaving a string in constructor without new or malloc is OK? Variable Name in this class is a pointer.

Dangee
  • 57
  • 4
  • 2
    the string "Hello" is a string literal which exists throughout the duration of the program. Similar: https://stackoverflow.com/questions/2579874/lifetime-of-a-string-literal-returned-by-a-function – PYA May 08 '18 at 01:50
  • Read about program segments, especially data segment, you will understand where this "Hello!" exist. btw there is so many errors in this small example – Mateusz Wojtczak May 08 '18 at 02:04
  • 2
    `kio=test(7,"Hello!",foo)` -- here, `kio` is a pointer. This will not compile, which tells me that the shown code is not the actual code. As such, any answers to this question will be meaningless, since they will not be based on real code you're working with. – Sam Varshavchik May 08 '18 at 02:35
  • Please post code that actually compiles and exhibit's the behavior you are describing. The code you posted has many, many mistakes and will not compile. – Galik May 08 '18 at 03:39

4 Answers4

2

The string "Hello" is a string literal which exists through out the duration of the program. So you can always point to it without breaking pointers. It wont be destroyed at the end of the function.

PYA
  • 8,096
  • 3
  • 21
  • 38
1

Your code has undefined behavior (which means a crash is not guaranteed!), but not for the reason you think it does.

InAFunc() takes a test object by value, so a copy of the input test object is made when InAFunc() is called. Any modifications that InAFunc() makes to its kio parameter are local to InAFunc() and not reflected back to the caller.

The mmk variable in main() is default-constructed, so presumably mmk.Name and mmk.ARR are NULL (you didn't show the code for that constructor, though), and InAFunc() will not overwrite that. It is undefined behavior to pass a NULL char* pointer to operator<<, or to index into a NULL int* pointer.

You probably wanted InAFunc() to output the new test object that it creates. In which case, the kio parameter needs to be passed by reference instead of by value:

void InAFunc(test &kio)

Now the mmk variable in main() will receive the values that InAFunc() assigns. mmk.Name and mmk.ARR will not be NULL anymore.

You would now be assigning a pointer to a string literal to mmk.Name, and a string literal resides in persistent read-only memory for the lifetime of the process, so passing mmk.Name to operator<< will be well-defined and not crash.

However, mmk.ARR will indeed be pointing to an array that is local to InAFunc() and will not be valid anymore once InAFunc() exits, as you suspected. So, you would have undefined behavior when you try to index into mmk.ARR (though the memory that mmk.ARR is pointing at will likely still be allocated, so the code will likely not crash).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Why leaving a string in constructor without new or malloc is OK? Why assign string to pointer is safe in constructor?

In C++, everything are objects:

  • An int is an object.
  • A string literal is an object.
  • A pointer too is an object which can be assigned.

Thus, the pointer Name is pointing to the location where the string literal resides.

Joseph D.
  • 11,804
  • 3
  • 34
  • 67
0

oh,i didn't figure out what the problem is. constant string literal is in an area(read only section) which managed by compiler, it will be free until the program stops. String literals: Where do they go? .....................................

The type of "hello" is char*(in fact char[6]), rather than a string. char* can be used as string because of the implicit conversion, std::string has a constructor which accepts char* as parameter. http://en.cppreference.com/w/cpp/string/basic_string/basic_string

btw, "kio=test(...)" cannot compile.

rsy56640
  • 299
  • 1
  • 3
  • 13