Reputation: 463
Recent times I am confused with the use of new keyword with the string data type. Can you please try to clarify it
What's the difference between the following string initialization:
1)
string* name = new string("abc") ;
....
delete name;
2)
string name = "abc";
Is it advisable to use new keyword , as the values within string is any how stored in heap as internal buffers of std::string
. It will be good if anyone explains it with storage location.
What's the difference between returning the string vs string*
string* name()
{
string* name = new string("abc") ;
return name;
}
string name()
{
string name = "abc";
return name;
}
Upvotes: 0
Views: 103
Reputation: 14323
There are several reasons to prefer the second approach over the first:
Most important reason: a string
is a string
, period. A string*
may point to a string
, or it may be NULL
/nullptr
, or it may point to a random location in memory. Therefore, you should use plain old string
's over string*
's wherever possible as using them is less prone to errors.
Declaring a string
object places it on the stack, meaning that it will automatically cleaned up when it leaves scope. Using new
means that you now have to manually clean up your allocated memory.
new
is a relatively slow operation. Using stack variables is much faster.
While string
store's its data on the heap, allocating the string
itself on the heap still adds another level of indirection.
Upvotes: 1
Reputation: 2995
string
is an actual string being created in the current scope, and it will be cleaned up automatically when the scope exits.
void function() {
{ // a scope
string test = "hi";
}
// test is destroyed here and cannot be used.
}
string*
is a pointer to a string that isn't tied to the current scope. A pointer starts out as invalid (usually assigned nullptr
by the user, which means it doesn't point to anything), and you need to assign a memory location to it; it would be an error to access it if it wasn't. When you use new
and assign a value to the pointer, then you have a string that is located on the heap and not in the current scope, and you need to delete
it manually, otherwise the memory is leaked. You can wrap a pointer in a smart pointer to have it delete itself automatically.
void function() {
{
string *test = new string("hi");
}
// test is *not* destroyed and memory was leaked
}
void function() {
unique_ptr<string> test;
{
test = unique_ptr<string>( new string("hi") );
}
} // test is deleted when the function exits and the unique_ptr goes out of scope.
The main reason to avoid allocating objects with new
is that it is slower than using items located on the stack, and the main reason to use new
is that it may be faster to pass around a pointer to an object rather than copying the object.
However, while copying a string may be slow, you can also move a string, which makes it fast.
Moving a string simply relocates the internal buffers of string A into string B
string function() {
string test = "abcdefg";
return test; // when test is returned, it is moved to the calling function.
}
You can also move a string explicitly.
string A = "hello";
string B( std::move(A) );
// A is invalid, and B contains "hello"
Usually std::strings are not created with new by themselves, but rather a struct or class they reside in may be.
An example using pointers, I may have a special class that I pass around to different functions:
class MyClass {
string a;
public:
const string *function1() { return &a; }
const string &function2() { return a; }
string function3() { return a; }
}
MyClass::function1
gives me a const pointer to the string, meaning no data is copied, and I can only read the string's value.
MyClass::function2
basically does the same thing as function1, but it uses a reference instead, references are like pointers but they must always contain a valid target. References are usually used in C++ over pointers.
MyClass::function3
returns a copy of the string, which an outside function can modify and it won't affect the one inside the class.
Upvotes: 1
Reputation: 311
If we are using the new operator, the object will be created in heap memory and the reference pointer will be in stack. In your example,
string* name()
{
string* name = new string("abc") ;
return name;
}
name is a pointer variable which is stored in stack, that contains the address of string object. The actual object is stored in the heap. So it wont be destroyed after the method execution. The calling method will get the address of the object and we can refer it using that. We need to deallocate the string object memory using the 'delete' keyword.
Ex:
delete name;
If we are defining a string without new operator, it will be created in the stack itself and it will be automatically destroyed when the method execution gets over. Consider the example,
string name()
{
string name = "abc";
return name;
}
Here one object will be created in the stack frame of method name, after the method execution over, it will get destroyed.
The statement that uses the above function will be like
string a = name();
Here the operator=() method for the string class will be invoked and a new object will be created in the calling function's stack frame.
Hope this will help
Upvotes: 0