I have got a quick question. I have the following code:
class Class1
{
Class1();
~Class1();
void func1();
private:
char* c;
}
void Class1::func1()
{
string s = "something";
this->c = s.c_str();
}
will c store "something" when func1() finishes?
No. It will invoke undefined behavior instead. (if you dereference the pointer, anyway.) Since s is a block-scope object with automatic storage duration, it is destroyed when the function returns, and that renders the pointer returned by .c_str() invalid.
Why not use an std::string member variable instead?
s is a local variable of type std::string in Class::func1. Once func1() finishes, the string s will go out of scope.
Any pointers you have with the address of s stored in them will become dangling pointers.
It will store a dangling pointer that you must not access. It may contain the string "something" or it may not. It doesn't matter, because accessing it is undefined behaviour, and should be avoided completely.
If you want to copy the string do this:
c = strdup( c.c_str() );
And don't forget to free(c) in ~Class1()
Beware that if you call func1 twice, you will leak memory. You probably want to initialise c to NULL in the constructor, and call free(c) before reassigning it in func1.
Surely a better approach is to store a std::string instead of a char*, which manages memory properly for you.
The variable s, will go out of scope once control exits that block, at which point its destructor will be called.
When is an object "out of scope"?
Related
void func( int x )
{
char* pleak = new char[1024]; // might be lost => memory leak
std::string s( "hello world" ); // will be properly destructed
if ( x ) throw std::runtime_error( "boom" );
delete [] pleak; // will only get here if x == 0. if x!=0, throw exception
}
For the above code, s is destroyed at the end of the function scope.
Is it possible to manually call the destructor on the object std::string?
Is it possible to manually call the destructor on the object std::string?
Technically yes, it is possible to call the destructor of an automatic variable. But if the execution leaves the scope that has a destroyed automatic variable, the behaviour of the program would be undefined, so doing this is of little use in practice. You don't want your program to have undefined behaviour.
Explicit call to destructor is typically used when you've reused storage (typically an array of char or std::byte) for an object or array of objects using the placement-new expression.
Hows to do this?
You call the destructor just like you would call a member function. The name of the destructor is ~T for a class named T. In the particular case of std::string and other type aliases within a namespace, you need to do some gymnastics to get around grammar limitations. All of below are correct:
s.std::string::~string();
s.~basic_string();
using std::string;
s.~string();
P.S. s has automatic storage, not static.
This is from a small library that I found online:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ... rest of the function ...
return out.str().c_str()
}
In my code I am doing this:
const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;
Now, at first d contained garbage. I then realized that the C string I am getting from the function is destroyed when the function returns because std::ostringstream is allocated on the stack. So I added:
return strdup( out.str().c_str());
And now I can get the text I need from the function.
I have two questions:
Am I understanding this correctly?
I later noticed that out (of type std::ostringstream) was allocated with static storage. Doesn't that mean that the object is supposed to stay in memory until the program terminates? And if so, then why can't the string be accessed?
strdup allocates a copy of the string on the heap, which you have to free manually later (with free() I think). If you have the option, it would be much better to return std::string.
The static storage of out doesn't help, because .str() returns a temporary std::string, which is destroyed when the function exits.
You're right that out is a static variable allocated on the data segment. But out.str() is a temporary allocated on the stack. So when you do return out.str().c_str() you're returning a pointer to a stack temporary's internal data. Note that even if a string is not a stack variable, c_str is "only granted to remain unchanged until the next call to a non-constant member function of the string object."
I think you've hit on a reasonable workaround, assuming you can't just return a string.
strdup() returns a char* pointer that is pointing to memory on the heap. You need to free() it when you're done with it, but yes, that will work.
The static local variable std::ostringstream out makes no sense in this case, unless the std::string being returned was also static which your observation is showing to be not true.
In GetHandStateBrief, variable out does not need to be static. You need an explicit static string to replace the temporary that was being created in your original call to out.str():
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
I would like to have a class contain a std::unique_ptr initialized by the constructor then used elsewhere in the class.
So I've got a class that contains a std::unique_ptr like this:
class ObjectA
{
public:
ObjectA();
~ObjectA();
void SomeFunction();
private:
std::unique_ptr<ObjectB> myPointer;
}
Then in the class's source file myPointer is setup in the constructor and used in SomeFunction().
ObjectA::ObjectA()
{
ObjectC objectC;
myPointer = std::move(std::unique_ptr<ObjectB>(objectC.getPointer())); //setup pointer
}
ObjectA::~ObjectA() {}
void ObjectA::SomeFunction()
{
//use myPointer here
}
The problem though, is that I can't use myPointer in SomeFunction(), and here's why.
Obviously myPointer must be allocated on the heap to assure it doesn't get destroyed when the constructor is done executing. Assume that ObjectC and consequentially it's functions are from an external library. When I call ObjectC::getPointer() the pointer that's return is probably allocated on the stack apposed to the heap. Now I assume this is the case because right after the constructor has finished executing I get an error.
Basically I'm relying on a function to give me a pointer with wich I can then use elsewhere. However, the function allocates the object on the stack instead of the heap.
Is there some special way to solve this problem, maybe with a double pointer? Or will I just have to call ObjectC::getPointer() every time I want to use the pointer inside each execution block? If I had lots of functions inside ObjectA which rely on myPointer then calling ObjectC::getPointer() per function would be redundant, but I don't know if there is a better way to fix this, and I feel like a function (ObjectC::getPointer()) shouldn't force me into that redundancy.
When you call ObjectC::getPointer(), you don't just get "a" pointer. The function must specify what operations are valid on the pointer, and in particular how it should be disposed.
Usually, that would be delete, but it could also be e.g. fclose. You'll have to read the documentation. If the lifetime of the returned pointer matches that lifetime of objectC, then the lifetime of objectC should match myPointer. So it probably should be a member, and that in turn means that myPointer might be redundant. You could just substitute private: ObjectB& getB() { return *myObjectC.GetPointer(); }
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.
#include <iostream.h>
using namespace std;
class A {
public:
virtual char* func()=0;
};
class B :public A {
public:
void show() {
char * a;
a = func();
cout << "The First Character of string is " << *a;
}
char * func();
};
char* B::func() {
cout << "In B" << endl;
char x[] = "String";
return x;
}
int main() {
B b;
b.show();
}
The problem in this is that I am returing a local varibale pointer/reference.
Currently it is char x[]="String", but when I use a pointer char *x="String", the result is "S" but when Array reference the output comes as (i)
When you do something like:
char *f(){ return "static string"; }
You're returning the address of a string literal, but that string literal is not local to the function. Rather, it is statically allocated, so returning it gives well-defined results (i.e. the string continues to exist after the function exits, so it works).
When you (attempt to) return the address of an array of char like this:
char *f() {
char x[] = "automatically allocated space";
return x;
}
The compiler allocates space for x on the stack, then initializes it from a string literal to which you don't have direct access. What you're returning is the address of the memory in the stack, not the string literal itself -- so as soon as the function exits, that array ceases to exist, and you have no idea what else might be put at that address. Trying to use that address causes undefined behavior, which means anything can happen.
That is because, when B::func() the memory allocated for the x[] is released hence if you try to access that memory location afterwards you will get garbage values. But when you do char *x="String", the memory for the string "String" is most probably allocated only once from the read-only section of your process memory. This address is guaranteed to remain valid until the execution of your program. In that case, if you try to access the pointer variable it will work correctly. BTW, as a side note, you need to declare a virtual base class destructor.
First off, figure out how to post code blocks. It's not hard, just indent them by four spaces.
Second, you should never return a pointer to a function-local variable. Because they're allocated on the stack, and all bets are off as regards to whether they're around after the function returns.
EDIT: This was written when the provided code was butchered and incomplete. My point doesn't apply to this particular case, but it's still important to know.
To try to be more precise: B::func() is returning a pointer to a hunk of memory that it used for a temporary array. There are absolutely no guarantees what is in that memory once the function returns. Either (1, simplest good practice ) the calling function can allocate memory and pass in a string buffer for the called function to use or (2) the called function needs to allocate a buffer and the calling function needs to later release it (but this requires a very disciplined approach by the developer of the calling function, and I'd never want to rely on that) or (3, probably really the best practice) the calling function can pass in some sort of smart pointer that will release its memory when it goes out of scope, and have the called function use that smart pointer to point to the memory it allocates.