In Java you can call a class method without creating a variable with the instance of the class and still call that class method:
new Database().GetSomeValuesOutOfSomeTableJava();
If I try the same with C++ I get an error:
new Database()->GetSomeValuesOutOfSomeTableCpp();
Am I doing it wrong? How can I achieve the same result?
new Database().GetSomeValuesOutOfSomeTableJava();
That does create an instance (note the new); it then abandons it for the garbage collector to clean up.
In C++, you can create a temporary object without new:
Database().GetSomeValuesOutOfSomeTableCpp();
This will do the same as the Java example, except that the temporary will be destroyed deterministically at the end of this statement.
Whether you should be creating temporaries like this is another matter.
You would do this:
(new Database())->GetSomeValuesOutOfSomeTableCpp();
But you'd be leaking memory, so that's a pretty bad idea. Also, note that that this (both in C++ and Java) does indeed create a new instance. It's just a new instance that's not stored in a variable.
A better version might be something like this:
{
Database temporary;
temporary.GetSomeValuesOutOfSomeTableCpp();
}
Using RAII to initialize and properly destroy the temporary, and scoping to ensure it doesn't exist for longer than you'd like it to and mess up any later scoping.
Alternatively, as pointed out by Mike Seymour, you could do:
Database().GetSomeValuesOutOfSomeTableCpp();
Which will also avoid the memory leak.
Related
I am wondering a bit about object initialization in C++. I read using the 'new' keyword should be avoided if possible, since I don't need what it offers (dynamic allocation, right?), and I don't want to have to delete the object manually. I am having troubles calling the initialization of my object without using new though. I have this class:
class Apodization {
public:
Apodization()
{
std::cout << "Constructor for Apodization" << std::endl;
}
}
and this code:
Apodization* apoObj();
// Apodization* apoObj = new Apodization();
The print happens as expected when using new to create the object, but not without. I'm guessing this is because I'm only creating a pointer of Apodization type in the example above, but I don't know where to go from there. I would like to know the proper way to initialize an Apodization object without using the new keyword. Thanks for the help! I am finding C++ classes a bit weird coming from Java and Python.
An Object is initialised without new using RAII (Resource Allocation is Initialisation). What this means is that when you declare an instance of Apodization, memory for the instance is allocated on the stack and then the constructor is called to set up the initial state.
This means that simply writing:
int main(){
Apodization apodization;
//apodization.doSomething();
return 0;
}
is all you need to get the ball rolling!
(Being a Java guy myself, I love the succinctness of this!)
As the object is allocated on the stack, the destructor will automatically be called at the end of the scope; no manual memory management required.
P.S. I highly recommend you read Bjarne Stroustrup C++11 Programming Guide!
You can't. The new operator allocates memory for an object, calls the constructor for that object, and then returns the pointer. In your code, all you are doing is declaring the pointer without any memory being set aside for it, or a constructor doing any work. It is just a pointer to nothing.
Just create a static instance:
static Apodization apoObj; // This will create an instance of the object.
If you wish to use a pointer to access it then point to the static instance:
static Apodization SapoObj; // This will create an instance of the object.
static Apodization* apoObj = &SapoObj;
I'm wondering if it's possible to access all of the userdata "tables" (is it called userdata tables?) and then delete them from Lua because this is my problem:
a = Object(5, 5)
a:Delete()
a:SetPosition(3,3)
As you can see first I create an object and save an pointer to a c++ class called Object which is allocated using "new" in my map class. Then I delete the object which means I delete the allocated memory for the pointer in my map class. And last I call SetPosition, if the memory still is allocated for the c++ Object class everything will run fun. But if it is deletes (as it is in this case because we called Delete() before the SetPosition(...) call) my program will crash. So what I'm wondering is following:
Is it possible to set the varaible 'a' in lua to nil by calling Delete ? I know I could do something like 'a = a:Delete()' if Delete return nil but if I forget to do the 'a =' part it fail. Also I'm wondering if it's possible to delete the userdata and check if it doesn't exist when I call SetPositon(), if it doesn't I will just return.
Also, the base code is from: http://lua-users.org/wiki/SimpleCppBinding
First, let me answer your question:
Is it possible to set the varaible 'a' in lua to nil by calling Delete ?
No. There is no means to do what you're saying. And there's a reason for that: what you're trying to do is terrible code.
Lua is a garbage collected system. Lua should not be expected to delete objects. If Lua gets a pointer to some external object, then either your code owns it or Lua owns it.
If your code owns it, Lua should not be deleting it. Lua can use it for some period of time. But it is up to your Lua code to use it for exactly and only that period of time. Once its lifetime has expired, Lua shouldn't be talking to it anymore.
This is no different from dealing with pointers to objects in C and C++. If your function is handed a naked pointer (ie: not a smart pointer), your code needs to know how long it can reasonably expect to talk to that object. Can it store it? How long can it store a pointer to that object? When will that object die, and who's responsible for destroying it?
If you pass an object to Lua such that Lua now owns the object, Lua shouldn't be explicitly deleting it either. Lua is a garbage collected system; you should attach a __gc metamethod to your type, so that Lua's garbage collector will call your code when the userdata is collected. That way, you can call destructors, free memory, etc.
When you give Lua something that now belongs to Lua, it should look like a regular Lua object. You don't call Delete methods for tables and strings you create in Lua; you let the garbage collector do its job. It is your job, as the one writing the C++-to-Lua interface, to ensure that the objects you give to Lua behave the way that Lua wants them to.
In cases where you need to do significant resource management, where you want Lua to release resources as quickly as possible (such as for file handles, etc), then you need to store a pointer to your C++ object inside of the non-light userdata. That's the pointer you NULL out. All of your interface functions on that object will check the pointer to see if it's NULL and simply do nothing or raise an error.
Lua's file handles (returned by io.open) are a good example of this. If you try to call functions on them, Lua throws a Lua error.
In the Delete method, set the metatable of the received object to nil and you'll get an error message if you later call a method on that object.
I'd rather advice using SWIG or LuaBind instead, they've already taken care of such pitfalls for you.
I am trying to embed lua in an existing C++ application and have made a standard procedure for it by inheriting from a class that does the work.
The serious problem I see is that if the exposed object gets deallocated or deleted in the C++ environment then a call from Lua will cause crashes. If the memory is being deleted by the program using 'delete' then I can maybe write a wrapper on delete to take care of deallocation in Lua as well, but if the memory was allocated by C++ and deallocated when the appropriate variable is out of scope I don't see a way on how to find that out and then take appropriate actions in the lua space, anybody has any ideas on this?
Thanks.
In general, virtually every Lua wrapper has some way to decide who owns what memory. That is, whether an object is owned by (and therefore will be deleted by) Lua or by your application.
If you have given Lua a pointer to an object that C++ owns, then you must find a way to ensure that Lua does not use this pointer past the point where C++ deletes it. There are several ways to avoid this. One way is to transfer ownership to Lua.
Another way is to use a boost/std::shared_ptr, which allows you to share ownership between C++ and Lua. If you're manually doing this, then you are creating some non-light userdata which is the size of a shared_ptr in Lua. You attach a cleanup metamethod to it that will destroy the shared_ptr, and you use placement-new to construct the shared_ptr on the Lua userdata. Luabind actually has this built-in as a feature: if you pass a shared_ptr to Lua, then they both share ownership of the memory.
You could also use a boost/std::weak_ptr. This is an object that you query to get a shared_ptr. The idea is that you're not supposed to keep the pointer around; you query it temporarily as needed, but you only store the weak_ptr permanently. If the object has lost all of its shared_ptr references, then querying the weak_ptr will return a null pointer.
You will have to use an RAII wrapper that can bind to the Lua instance using the registry and expose the values to Lua using a table- you can remove an internal pointer from it when you're done.
template<typename T> class LuaExposedValue {
T t;
lua_State* ls;
public:
LuaExposedValue(lua_State* L) {
// set registry[&t] = { &t }
ls = L;
}
~LuaExposedValue() {
// remove &t from the table
}
}
Alternatively, just ban Lua from accessing it after the variable is gone and let the scripter worry about it.
Finally, you could just allocate everything that Lua can access using the Lua GC.
Disclaimer: I wrote the library I'm about to recommend
You might want to try using this LuaWrapper Library that sounds like it'll handle what you're trying to do. It's not even really a library, it's just a single header file.
You can use luaW_push<MyType>(L, myObj); to push your objects into Lua. Lua will not own the objects you create from C++ unless you run luaW_hold<MyType> on them. In other words, unless you tell Lua to, it will not garbage collect your object.
Conversely, you can use MyType.new() in your Lua code to create an object, which Lua does own. It will be garbage collected as you would expect. If you want to pass ownership to C++ you can call luaW_release<MyType> on your object.
There's also functions like luaW_to<MyType> and luaW_check<MyType> and to a limited degree it correctly supports inheritance from base types (though at the moment it only allows for single inheritance). I find that this greatly simplifies my own attempts at using C++ and Lua together because it make managing pointer ownership very straightforward.
I have two four classes:
MainClass (class where things start)
XmlReader (class used to parse an xml file)
SerialPortSettings (holds info about the serial port read from the xml-file, e.g. baud rate, comport etc)
SerialPortListener (takes a reference to a SerialPortSettings object in its constructor)
MainClass has a method to read things from an xml-file.
In this method, it first creates an instance of XmlReader and gives it an xml-file as a constructor parameter. This xmlReader does only need to exist within this method:
XmlReader xmlReader (xmlFile);
The xmlReader parsers the xmlFile. MainClass gets access the xml-stuff by calling get-methods in XmlReader. So far everything is good.
However, one of the methods XmlReader offers, is a method which creates an object of type SerialPortSettings based on the information read from the xml-file:
SerialPortSettings* XmlReader::getSerialPortSettings() {
.... // reading stuff from xml file
return new SerialPortSettings(baudRate, dataBits, comport);
}
This method is called from MainClass and the return value is stored in a pointer:
SerialPortSettings* settings = xmlReader.getSerialPortSettings();
The next thing the MainClass does is to create a SerialPortListener (which is a member-variable that has to exist until MainClass is exited). SerialPortListener takes a reference to a SerialPortSettings in it's constructor:
m_serialPortListener = new SerialPortListener(*settings);
Hence SerialPortSettings also has to exist until MainClass exits, therefore I have created this as a pointer.
So here is the clue:
In the SerialPortListener destructor I tried to delete the SerialPortSettings-object:
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
Then in the MainClass destructor I deleted the SerialPortListener-object:
MainClass::~MainClass() {
delete m_serialPortListener;
}
This fails. I get an error saying that I deleted something twice in the main-class:
*** glibc detected *** ./ioserver: double free or corruption (out): 0x00860d80 ***
When I remove the delete &m_settings from SerialPortListener, it works fine.
But when should pointer be deleted? What is the correct thing to do? I really want my xml-reader to create the SerialPortSettings - object, insted of returning all of the info (baud rate, comport etc) to MainClass and create the SerialPortSettings object itself.
A good solution is to simply let xmlReader::getSerialPortSettings return a SerialPortSettings by value.
Let the compiler do the optimization.
But where you do need to handle pointer lifetimes, do use smart pointers, such as std::auto_ptr or boost::shared_ptr. The key idea is to define ownership. The owner (which in the case of boost::shared_ptr is the collection of smart pointers referring to the object) is responsible for deleting – no-one else.
Cheers & hth.,
The pointer should be deleted at the end of MainClass.
It makes no sense (to me, at least) to use delete on a reference.
It would be way cleaner to not have the XML reader create new objects; treat SerialPortSettings as a "dumb" container, and just pass in a reference to fill in with data from the XML:
XmlReader::getSerialPortSettings(SerialPortSettings& settings);
the actual instance can then be a local variable in the main program, and be passed (by const reference, this time) to the serial port when it's created:
SerialPortSettings portSettings;
m_xmlReader->getSerialPortSettings(portSettings);
m_serialPort = new SerialPort(portSettings);
the life time of the settings instance is then naturally the same as the scope it's in, since it's just a local variable.
If the method in the main class that reads XML needs to exit before the serial port goes out of scope, you could make the settings a member variable of the main class, instead.
What is the datatype of m_settings? Is it a SerialPortSettings* or a SerialPortSettings? If the latter, you can't delete it like that anyway, as it's allocated on the stack. If it's the former (a pointer), you do not need the reference operator. Simply write delete m_settings;
A simple typo in your delete:
delete &m_settings;
should be:
delete m_settings;
For any pointer you should decide who owns the pointer, and that should be who deletes it.
Or you can use a smart pointer such as shared_ptr and eliminate the problem altogether.
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
That block looks quite weird. Are you sure you aren't trying to delete value by reference? Cause C++ does it automatically when you delete the class, so your delete is really trying to delete twice.
OK, first of all, you're missing the truly important bit of information which is HOW is SerialPortListener::m_settings being stored. Because of the error you're getting, I'm guessing you're actually storing a copy of it, which means: I bet you have something like this:
class SerialPortListener {
SerialPortSettings m_settings;
SerialPortListener(SerialPortSettings set) {
m_settings = set;
}
}
if it's something similar to this, then the listener is saving a copy of the object in it's own memory, and deleting it doesn't make sense, since it's not a pointer. Rule of thumb, never do delete &anything until you know what you're doing and realize you really need to.
In terms of "correctness", the pointer should be freed by the main class, since it was who created it. Or if you don't have any use for it in the main class, and want the listener to delete it, save a pointer instead of an object or reference in the listener.
I ended up making m_serialPortSettings a pointer in SerialPortListener, and deleting it from there.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When to use “new” and when not to, in C++?
When should I use the new keyword in C++?
It seems like I could program something without ever using the word new, and I would never have to worry about deleting anything either, so why should I ever call it?
From what I understand, it's because I would run out of stack memory.
Is this correct? I guess my main question is, when should I call new?
It's a matter of object lifetime: if you stack-allocate your objects, the objects destructors will be called when these objects go out of scope (say, at the end of the method). This means that if you pass these objects out of the method that created them, you'll find yourself with pointers to memory that could be overwritten at any time.
It's because you may not know at compile time whether you need an object, or how many, or of what type. The new operator allows you to dynamically allocate objects without having to know such things in advance.
Here's an example of not knowing the type of object in advance:
class Account { ... };
class CheckingAccount : public Account { ... };
class VisaAccount : public Account { ... };
...
Account *acct = type == "checking" ? new CheckingAccount : new VisaAccount;
The main reason you'll need to use new/delete is to get manual control the lifetime of your objects.
Other reasons are already provided by others but I think it's the more important. Using the stack, you know exatly the lifetime of your objects. But if you want an object to be destroyed only after an event occurs, then it cannot be automatically defined.
The lifetime of the data/objects created on the stack is restricted to the block. You cannot return references/pointers to it. For data to be available across functions, you can create it on the heap with new. Of course, it can be at a higher level, or even global. But you seldom know at compile time how much data/how many objects will be needed at run time.
You can write a many non-trivial programs without ever calling "new." (or thus delete).
What you wouldn't be able to do (at least without writing or using your own equivalents) is decide what type of objects or how many you want to create at run-time, so you'd be limiting yourslef.
[updated]
You can use new to create new instance of some class, or allocate memory (for array for example), like
Object o = new Object();
Before creating new instance of class Object, you cannot use it. (Unless you have static methods.)(this is just one example of usage, sometimes other objects will instantiate or destroy objects that you need/don't need)
There are many good answers here but it is difficult to explain everything about new in one reply on SO, and if you do not understand what happens when new is called then it is difficult to know when to use it. This is one of the most important areas in programming so, after reading basic information here you should study it in more detail. Here is one of possible articles where you could start your research:
http://en.wikipedia.org/wiki/New_%28C%2B%2B%29
Topics that you will have to learn in order to understand what happens when you call new, so that you then could understand when to call it (there are more probably but this is what i can think of now):
- constructors (and destructors)
- static classes and methods
...