tolua++: Transfer pointer ownership to lua gc - c++

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

Related

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.

MessageBox shows Japanese characters when using return value from a function [duplicate]

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();

Difference between following declarations

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

Does this function leak memory?

The function below tests if the input string contains a double.
bool is_double(const std::string& str)
{
char* p;
strtod(str.c_str(), &p);
return *p == 0;
}
What happens to pointer p after the function returns?
You have two variables to consider: str and p.
The string str is passed as a const reference, so it's lifetime must be managed outside the scope of this function, so it cannot be leaked by this function.
With the character pointer p, we can consider the pointer itself and what it points to. According to the documentation, it is set to "...point to the first character after the number." Meaning, it points to memory inside the string you've passed; it does not get set to newly allocated memory. Since you're already managing the lifetime of str properly, and nothing new has been allocated, you don't have to free what it points to. The pointer variable itself is created on the stack, so its lifetime is that of the function.
So, no, you're not leaking.
A resource leak happens when you allocate a resource that becomes unreachable outside a certain scope and you didn't free it nor can get back a reference to it, whether that resource is dynamic memory, mutexes, or any other process-bound resource.
In your case, you're creating some variables and using a function that doesn't do any dynamic memory allocation so all of your stuff are in the stack => no memory leak because it's "freed" once you return from the function.
As the pointer is within the scope of your function and not declared as anything global, I believe it will be automatically erased after the execution of the function.
pointer p will is set by the function to the next character in str after the numerical value.
so it won't leak memory
also you can use
bool is_double(const std::string& str)
{
double d;
d = strtod(str.c_str(), NULL);
return d != 0.0;
}

Is string dynamically allocated?

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"?