Difference between following declarations - c++

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;
}

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.

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.

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

Related

How to free memory after strdup?

I have such class:
class Kot{
public:
string name;
};
I create an instance of it:
Kot* kot = new Kot;
kot->name = "John";
Then I want to create a duplicate of string:
string name;
name = strdup(kot->name.c_str());
I use strdup because I want to delete kot and use only name variable.
But I have a 5 bytes memory leak due tonamememory allocation.
How can I free it safely? I tried to dodelete &name`, but I have:
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
You probably detected a 5-byte memory leak, but it is not because of the string.
Each call to strdup creates a new char[] of the size matching the length of the string. You should bind it to a raw pointer char* and remove it at some point.
What you did instead, is that you create a temporary char* pointer. Let's call it temp for our purposes.
The temp string is then passed to std::string's constructor. The std::string makes another copy of it, leaving the original temp intact.
Then the temp pointer just dissapears, without properly clearing the memory.
At the end, when the std::string object is destroyed, it properly clears its own, private copy of the string. But the memory previously pointed by temp is never freed.
A quick fix would be to:
char* temp = strdup(kot->name.c_str());
name = temp;
free(temp);
However, you don't even have to do that! If you assign one std::string object to another, you make a proper copy of its contents already. So:
name = kot->name;
will most likely do exactly what you are trying to achieve already -- making a copy of kot->name within your name. In such scenario, name and kot->name become two completely separate strings with the same (copied) content. From that point onward, changing/deleting one does not affect the other.
You use free(), not delete.
Per the standard documentation:
The strdup() function shall return a pointer to a new string, which is
a duplicate of the string pointed to by s. The returned pointer can be
passed to free(). A null pointer is returned if the new string
cannot be created.
You have a memory leak here:
name = strdup(kot->name.c_str());
because you never release memory allocated by strdup.
To avoid this problem you can simply construct name from the kot->name:
name = kot->name;

Is it safe to return a std::string by value?

In the following code, a string is encapsulated within a class, Foo.
The call to Foo::getText() returns the string by value. This creates a second instance of the string object, but both string objects now point to the same char buffer on the heap.
When the Foo instance is deleted, the the encapsulated string is automatically destructed, and therefore the char buffer on the heap is deleted.
Even though getText() returns a string by value, the resulting string object still relies on the lifetime of the original string object in order to retain the char buffer to which they mutually point.
Doesn't this mean that the printing of the retval to the terminal is an invalid access to memory that has already been free'd on the heap?
class Foo
{
Foo(const char* text) :
str(text)
{
}
std::string getText()
{
return str;
}
std::string str;
};
int main()
{
Foo pFoo = new Foo("text");
std::string retval = foo.getText();
delete pFoo;
cout << retval; // invalid memory access to char buffer?
}
I think a lot of people assume that, because the string was returned by value, they need not be concerned about the lifetime of the original string within Foo. This problem isn't strictly related to strings, but really applies to any class with encapsulated pointers that are free'd upon destruction. But what's the best practice here when it comes to strings?
Never return string by value?
Only return strings by value if the lifetime of the original string is guaranteed?
Always make a copy of the string? return std::string(retval.c_str());
Enforce a contract with the caller of getText()?
EDIT:
I think I was misled by RVO. All three strings in this example return a c_str at the same address. Is RVO to blame?
class Obj
{
public:
Obj() : s("text")
{
std::printf("%p\n", s.c_str());
}
std::string getText() { return s; }
std::string s;
};
int main()
{
Obj* pObj = new Obj();
std::string s1(pObj->getText());
std::string s2 = pObj->getText();
delete pObj;
std::printf("%p\n", s1.c_str());
std::printf("%p\n", s2.c_str());
}
Result:
0x600022888
0x600022888
0x600022888
This creates a second instance of the string object, but both string objects now point to the same char buffer on the heap.
No, they don't.
std::strings own their contents. When you copy a std::string, you copy its buffer.
I think a lot of people assume that, because the string was returned by value, they need not be concerned about the lifetime of the original string within Foo.
And those people are right. There is no "sharing".
Your return by value is fine and you needn't think more about it.
I'd like to add some points to #LightnessRacesInOrbit's answer:
Never return string by value?
Never return local strings by reference or pointer. Actually, never return anything local by reference or pointer. By value is just fine.
Only return strings by value if the lifetime of the original string is
guaranteed?
Again, you're thinking backwards. Only return by reference or pointer if the lifetime of the original is guaranteed.
Always make a copy of the string? return std::string(retval.c_str());
C++ does this automatically for you, if it can't move the string out (RVO/NRVO). No need to copy manually.
Enforce a contract with the caller of getText()?
Not needed as you get a copy anyway
I think a lot of people assume that, because the string was returned by value, they need not be concerned about the lifetime of the original string within Foo. This problem isn't strictly related to strings, but really applies to any class with encapsulated pointers that are free'd upon destruction.
And their assumption is correct. Any class with a (working) copy-constructor can be copied as often as needed and every copied instance is completely independent from the others. The copy-constructor takes care of copying the heap-space.

tolua++: Transfer pointer ownership to lua gc

Is there a way to return objects allocated on the the heap to lua without 'caching' references to them?
Consider the following:
class foo
{
char const* bar() const
{
char* s = malloc(...);
...
return s; // << Leak. How to transfer the ownership of 's' to lua?
}
};
If I return a string to allocated memory i have to delete it.
Is there a way to transfer the ownership to lua?
Or is it even possible to get the lua_state* to implement string returning by myself using lua_pushstring(...)?
You can pass your string into Lua with the lua_pushstring function and free it afterwards:
Pushes the zero-terminated string pointed to by s onto the stack. Lua makes (or reuses) an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns. The string cannot contain embedded zeros; it is assumed to end at the first zero.
If you really want ownership to be transfered, consider wrapping your string into appropriate object with its own metatable and implementing __gc function.
By declaring a parameter 'lua_Sate* state' tolua++ will pass the Lua-State to the function.
With a return type of type 'lua_Object' you can return the stack-index to a lua object.
PKG
lua_Object MyFunctionReturningATable(lua_State* s);
CPP
lua_Object MyFunctionReturningATable(lua_State* s)
{
lua_newtable(s);
...
return lua_gettop();
}

c++ pointer scope

What happens when you have the following code:
void makeItHappen()
{
char* text = "Hello, world";
}
Does text go out of scope and get deleted automatically or does it stay in the memory?
And what about the following example:
class SomeClass
{
public:
SomeClass();
~SomeClass();
};
SomeClass::SomeClass() { }
SomeClass::~SomeClass()
{
std::cout << "Destroyed?" << std::endl;
}
int main()
{
SomeClass* someClass = new SomeClass();
return 0;
} // What happend to someClass?
Does the same thing occur here?
Thanks!
char* text = "Hello, world";
Here an automatic variable (a pointer) is created on the stack and set to point to a value in constant memory, which means:
the string literal in "" exists through the whole program execution.
you are not responsible for "allocating" or "freeing" it
you may not change it. If you want to change it, then you have to allocate some "non-constant memory" and copy it there.
When the pointer goes out of scope, the memory pointer itself (4 bytes) is freed, and the string is still in the same place - constant memory.
For the latter:
SomeClass* someClass = new SomeClass();
Then someClass pointer will also be freed when it goes out of scope (since the pointer itself is on the stack too, just in the first example)... but not the object!
The keyword new basically means that you allocate some memory for the object on free store - and you're responsible for calling delete sometime in order to release that memory.
Does text go out of scope
Yes! It is local to the function makeItHappen() and when the function returns it goes out of scope. However the pointed to string literal "Hello, world"; has static storage duration and is stored in read only section of the memory.
And what about the following example:
......
Does the same thing occur here?
Your second code sample leaks memory.
SomeClass* someClass = new SomeClass();
someClass is local to main() so when main returns it being an automatic variable gets destroyed. However the pointed to object remains in memory and there's no way to free it after the function returns. You need to explicitly write delete someClass to properly deallocate the memory.
The variable text does go out of scope (however the string literal is not deleted).
For objects that you allocate with new (like your SomeClass), you need to explicitly delete them. If you want objects allocated like this to be automatically deleted, take a look at boost smart pointers (std::unique_ptr if your compiler is c++0x aware).
This will automatically delete the allocated object when the shared pointer goes out of scope.
Your code would then look like this:
int main(int argv, char **argv)
{
boost::scoped_ptr<SomeClass> ptr(new SomeClass);
// the object is automatically deleted
return 0;
}
Note: In this particular example, you could also use std::auto_ptr (but this will be deprecated in c++0x).
Note 2: As was pointed out in the comments by Kos, it is in this case more appropriate to use boost::scoped_ptr or std::unique_ptr (c++0x). My answer first used boost::shared_ptr, which is more appropriate if you need to share ownership of a pointer between several classes for instance.
In the first example the string literal is stored in data segment of your executable.
In the second case you do not have to call delete (in your example program just terminates) since on program termination the heap is freed anyway for the process.
Note though that there are OS (as I have read) that you have to explicitly release heap even if the program terminates since it will not be cleaned up at termination for you.
Of course programmer is responsible for memory management in C++ and objects you create on heap should be deleteed once unneeded.

String literals inside functions: automatic variables or allocated in heap?

Are the string literals we use inside functions automatic variables? Or are they allocated in heap which we have to free manually?
I've a situation like the code shown below wherein I'm assigning a string literal to a private field of the class (marked as ONE in the code) and retrieving it much later in my program and using it (marked as TWO). Am I assigning a variable in the stack to a field in ONE? Can the code be referencing to a dangling pointer which in this case worked because the program was small enough?
I've compiled and ran it, it worked fine but I'm having a strange crash in my actual program where I'm assigning string literals to fields of the class like this and I suspect the case I mentioned above.
#include <iostream>
using namespace std;
class MemoryLeak
{
private:
char *s;
public:
MemoryLeak() {}
void store()
{
s = "Storing a string"; // ONE
}
char *retrieve()
{
return s;
}
};
int main()
{
MemoryLeak *obj = new MemoryLeak();
obj->store();
cout << obj->retrieve() << endl; // TWO
delete obj;
return 0;
}
Should I be declaring the variable "s" as a char array instead of a pointer? I'm planning to use std::string, but I'm just curious about this.
Any pointers or help is, as always, much appreciated :) Thanks.
String literals will be placed in the initialized data or text (code) segment of your binary by the compiler, rather than residing in (runtime allocated) memory or the stack. So you should be using a pointer, since you're going to be referencing the string literal that the compiler has already produced for you. Note that modifying this (which would require changing memory protection typically) will change all uses of this literal.
It is undefined behaviour to modify a string literal, and is most likely the cause of the crash in your program (ISO C++: 2.13.4/2). The standard allows for a conversion from a string literal to char* for backwards compatibility to C and you should only have that conversion in your code if you absolutely need it.
If you wish to treat the string literal as a constant, then you can change the type of your member to a const char *.
If your design requires that s can be modified, then I would recommend changing its type to std::string.
Thank you Cody and Richard.
I found the cause of the bug. It was because I was doing a delete on an object which was already delete'd. I was doing:
if (obj != NULL) delete obj;
I changed it to:
if (obj != NULL)
{
delete obj;
obj = NULL;
}
Learning C++ is definitely fun :)
Maybe the cause of the crash is that you did not 0-terminate the string?
Lets have a look at your options.
There are also a couple of things you should do:
/*
* Should initialize s to NULL or a valid string in constructor */
MemoryLeak()
{
store();
}
void store()
{
// This does not need to be freed because it is a string literal
// generated by the compiler.
s = "Storing a string"; // ONE
// Note this is allowed for backward compatibility but the string is
// really stored as a const char* and thus unmodifiable. If somebody
// retrieves this C-String and tries to change any of the contents the
// code could potentially crash as this is UNDEFINED Behavior.
// The following does need to be free'd.
// But given the type of s is char* this is more correct.
s = strdup("Storing a string");
// This makes a copy of the string on the heap.
// Because you allocated the memory it is modifiable by anybody
// retrieving it but you also need to explicitly de-allocate it
// with free()
}
What you are doing is using C-Strings. These should not be confused with C++ std::string. The C++ std::string is auto-initialized to the empty string. Any memory allocated is de-allocated correctly. It can easily be returned as both a modifiable and non modifiable version. It is also easy to manipulate (i.e. grow shrink change). If you grow a C-String you need to re-allocate memory and copy the string to the new memory etc (it is very time consuming an error prone).
To cope with dynamically allocating your object I would learn about smart pointers.
See this article for more details on smart pointers.
Smart Pointers or who owns you Baby
std::auto_ptr<MemoryLeak> obj(new MemoryLeak());
obj->store();
std::cout << obj->retrieve() << std::endl; // TWO
// No need to delete When object goes out of scope it auto deletes the memory.