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;
Related
I'm wrapping part of the FBX SDK (closed, with a public API) with Mono (so COM, CLI aren't options) and a bunch of extern's, and it was all going well until I had to return a non-pointer instance. See here
The crucial point is that I have to return it back to C++ for another call. Because I don't know how you'd do that without a pointer, I returned it as such:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
return &obj->GetFirstProperty();
}
..and it's not until I try something like the next snippet that I get the "System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt." message.
FBXAPI const wchar_t* Property_GetName(FbxProperty* prop)
{
int c = prop->GetSrcPropertyCount();
return L"Test";
}
If I use almost identical code using the same calls in C++, it's fine. I've done another ~20 function calls in the same manner but without having to "pointerfy" it, and they're all fine too, so I don't think my DllImport's are to blame. So if the reference is to be blame, how else do I do it? Surely I don't store a global static reference somewhere just because someone called it from the API?
Any help is appreciated, C/C++ and the explicit way it handles memory is new to me.
I assume your program is crashing because the property you were getting the pointer to does no longer exist. Let me clarify and start by dissecting the following:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
return &obj->GetFirstProperty();
}
I looked up the documentation of FBX, and FbxObject::GetFirstProperty() has a return type of FbxProperty. Notice that the return value isn't any pointer or reference? That means you get a so called 'auto-variable', or in this case a 'temporary'. This kind of object only lasts until you leave the scope, which in this case is your Object_GetFirstProperty() of your wrapper. After that, the object is cleaned up and removed from the memory stack. FbxObject::GetFirstProperty() gives you a copy of the property, not an actual reference. Internally it might be different, but your wrapper is concerned about the property object itself, not it's content.
So what you are doing is you get a pointer to an address that is no longer valid later on when you pass it to your Property_GetName().
C++ behaves differently than C# in regards to object lifetime. An object in C# called MyObj can be thought of as a C++ pointer type like MyObject* - it's a like a reference value. In C# you have also value-types like struct and so forth, which are the equivalent to the C++ auto-variable. All auto-variables are destroyed when their lifetime scope is left.
What you'd have to do to overcome your problem is to save the object you get from FbxObject::GetFirstProperty() directly, and not a pointer to it. You'd basically have to marshall the object into a proper .NET class so that it's contents are not lost.
Alternatively, you could just allocate dynamic memory and copy the object you get from FbxObject::GetFirstPoperty() there, and return a pointer to your own memory. Of course you'd have to delete this memory later on manually. Here is a simple example:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
// Allocate custom memory.
char* myMem = new char[sizeof(FbxProperty)];
// Copy the property's content there.
std::memcpy(myMem, &obj->GetFirstProperty(), sizeof(FbxProperty));
// Return custom memory address.
return reinterpret_cast<FbxProperty*>(myMem);
}
This should solve your memory corruption issue. But in C++ you'd have to free this memory manually when your are finished with the property by doing ths:
FBXAPI void Property_Free(FbxProperty* prop)
{
// Free previously allocated memory
delete[] prop;
}
But this attempt may cause other problems, depending on how the actual FbxProperty handles it's data inside. You are creating a copy of the object, sure, but if the original temporaty/auto-variable deletes important memory upon destruction, you would have similar issus to the ones you have now.
If you are REALLY witty you could just write real wrapper classes for every FBX type you require and marshall the whole class type instead of generating separete C functions you have to P/Invoke every time you want to get a value or a property.
I have been reading up on smart pointers and recently in class my TA said that we should never use raw pointers. Now, I've done a lot of reading online and looked at different questions on this website but I'm still confused on some aspects of smart pointers. My question is: which smart pointer would I use if I want it to be used across my program? I'll show some code.
So I have a basic Application class that makes declarations of objects from class AI. Note: I have two different smart pointers, a unique one and a shared one, for testing reasons.
// Application class in Application.h
class Application
{
public:
Application(){}
~Application(){}
//... additional non-important variables and such
unique_ptr<AI> *u_AI; // AI object using a unique pointer
shared_ptr<AI> *s_AI; // AI object using a shared pointer
//... additional non-important variables and such
void init();
void update();
};
// AI class in AI.h
class AI
{
public:
AI(){}
~AI(){}
bool isGoingFirst;
};
In the Application init function, I want to create the AI object, and then I want to use it in the update function. I am not sure if I am declaring my pointer right at all, but I know for a fact that it compiles and it works for assigning and printing out data in the init function. More code below.
void Application::init()
{
//.. other initialization's.
std::shared_ptr<AI> temp(new AI());
sh_AI = &temp;
sh_AI->isGoingFirst = true;
//.. other initialization's.
// Function ends.
}
void Application::update()
{
if(sh_AI->get()->isGoingFirst == true)
{
// Do something
}
else
{
// Do something else
}
// Other code below
}
Later in my program, the update function is called, which uses the same AI smart pointer that I declared in my class Application. What I have found out is that the smart pointer AI object is being deleted. I understand that smart pointers have automatic memory management, but is there a smart pointer that will allow you to use a it in different functions without creating any major problems, such as memory leaks or dangling references? Or am I missing the whole point of smart pointers?
I'm sorry if this was answered in another question but I read into a lot of the other questions, and while I understand more about smart pointers, I'm still learning. Thank you!
As Neil Kirk pointed out in the comments, these declarations are not what you want:
unique_ptr<AI> *u_AI; // AI object using a unique pointer
shared_ptr<AI> *s_AI; // AI object using a shared pointer
u_AI and s_AI are still objects to raw pointers. The whole point is to remove the need to manage the raw pointer directly. So now you replace them with:
unique_ptr<AI> u_AI; // AI object using a unique pointer
shared_ptr<AI> s_AI; // AI object using a shared pointer
to assign your created pointer, you use the function make_unique or make_shared:
u_AI = unique_ptr<AI>(new AI()); // Yu may be able to use make_unique like
// make_shared but it's new to C++14. may not be available
s_AI = make_shared<AI>();
Then, when you need to access them, you just pretend they are pointers, so in your update function:
if(sh_AI->get()->isGoingFirst == true)
becomes:
if(sh_AI->isGoingFirst == true)
As for when to use unique_ptr vs shared_ptr, you answer that by answering the following question: What do I want to happen when someone makes a copy of Application? i.e.:
Application app1;
app1.init();
Application app2 = app1; // ?? what happens to AI object in app2?
There are 3 possible answers:
I want there to be an extra copy of AI in app2. In this case you use unique_ptr and make sure you implement a copy constructor that does the copying.
I want app2 and app1 to share a copy of AI. In this case you use shared_ptr and the default copy constructor will do the job for you.
I don't want there ever to be a copy of Application. (Which makes sense for a class called Application). In this case it doesn't really matter (in which case I would default to unique_ptr) and remove the copy constructor:
Application(const Application&) = delete;
Short answer: Since your pointer is public, I suggest you use a shared_ptr. However, your pointer does not need to be public so if it was private you could use a unique_ptr since you only use it in your own instance.
The truth is though that it does not really matter much (and I know I'll get some downvotes with this). There are two reasons to use unique_ptr:
it never leaves your module and you just need a replacement for a naked pointer
you want to explicitly show that it is not supposed to leave your module.
On the other hand if you need to ever share the pointer (even in a read-only way) then you will have to use a shared_ptr.
A lot of times it is more convenient to use shared_ptr to begin with but for reason 2) above it is worth using unique_ptr.
Not a reason to use unique_ptr: performance. All I say is make_shared.
Now to your code
This is how you define a smart pointer:
std::shared_ptr<AI> s_AI;
std::unique_ptr<AI> u_AI;
This is how you initialize it:
s_AI = std::make_shared<AI>(); // or
s_AI = std::shared_ptr<AI>(new AI);
u_AI = std::unique_ptr<AI>(new AI);
Note that there is no std::make_unique in C++11. It's going to be in C++14 and it's not that hard to write a replacement but fact is that in C++11 there is none.
This is how you use the pointers:
s_AI->isGoingFirst;
That's it, it behaves like a normal pointer. Only if you have to pass it to a function that needs a pointer you need to use .get().
here is how you delete (empty) the pointer:
s_AI.reset();
Again, I suggest you make your pointer private. If you need to pass it out make sure you use a shared_ptr and write a getter method:
std::shared_ptr<AI> getAI() const {
return s_AI;
}
Remember that if you do this you can't assume that your AI object will be destroyed when your Application object is.
I'm using Visual Studio 2013 and C++11. I want to pass the address of a C++ object back to C. The C code will treat it as a opaque handle; C will never reference it. The only use will be to pass it back to C++ where it will again be used as a pointer to object.
I'm finding that if I create the object in C++ and pass it back to C, the object will be destroyed because it goes out of scope. As a work around, I created a global variable to hold the object so it won't be destroyed upon returning to C. What is the best practice? Should I use a ref-counted pointer type such as shared_ptr? How? I don't like the idea of casting to size_t or such.
The following is an attempt to demonstrate the question. Code won't work.
extern "C" _declspec(dllexport) void __stdcall SwbHttpListenW(const wchar_t *route, SwbHttpListen **listener)
{
*listener = &SwbHttpListen(route); // new will work but how about without new?
}
[Edited the code to re-ask for a solution not using new.]
How about heap allocating the C++ object using the new operator, and getting its address by using the ampersand (&) operator? By heap allocating the object, you ensure it will never be deleted until you actually use the delete operator on it, and the address could be stored/passed as an int.
A simple example:
int main() {
Person *a = new Person("Paul");
doSomething(a); //Passes the memory address of a to the function doSomething
//...and once you're finished using the object, you have to:
delete a;
return 0;
}
It's always going to be messy when you do this sort of thing, how you handle it really depends upon what you want the lifetime of your c++ object to be and, to a lesser extent, how you are going to get rid of it in the end. But clearly the c++ has to do any destruction, you cannot get the c to do that.
This sort of thing is an example of when it is not necessarily A Bad Thing to have global objects - though of course that means you cannot get rid of it freely. Alternatively, you could create it dynamically using new but you then will need an arrangement between the c and the c++ so that it gets deleted at the right time - you might end up with a global object pointer or maybe the c could pass the pointer back to get it destroyed - that would be the nicest solution.
Some trouble may be if some automated Garbage Collector are in use (it may be in C++). std::declare_reachable , std::undeclare_reachable may help.
Else the trouble really doesn't concern passing a pointer to C. And you need to develop some way to achieve a proper pointers to valid objects at the places where necessary... :-)
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.
So I have declared a vector in my class header like this:
...
private:
vector<Instruction> instructions;
...
Then in the .cpp implementation in the constructor, I try to initialize it like this:
instructions = new vector<Instruction>();
Xcode tells me: No viable overloaded '='
I am basically trying to get this class to behave like I would expect in java, where instances of the class retain this vector. Thats why I wanted to dynamically allocate it using new, so as to make sure that it doesn't get lost on the stack or something. Any help would be appreciated with this, thanks so much.
In order to do what you're trying to do the instructions = new vector<Instruction>() line is entirely unnecessary. Simply remove it. The vector will automatically get default-constructed when an instance of your class gets constructed.
An alternative is to make instructions into a pointer, but there doesn't appear to be any reason to do this here.
when you write
vector<Instruction> instructions;
you already have instantiated instructions to whatever memory model the user of your class is using e.g.
class YourClass
{
vector<Instruction> instructions;
};
...
int main()
{
YourClass class1; // stack
std::unique_ptr<YourClass> class2(new YourClass); // heap
...
}
In your class, you declare a std::vector<Instruction>. new vector<Instruction>(); returns you a std::vector<Instruction>*.
operator new returns a pointer, so you have a type mismatch.
The real issue is the fact that you are doing it at all. Do you have a good reason for dynamically allocating that vector? I doubt it, just omit that entirely as it will be allocated along with instances of your type.
You have a member value but you try to initialize it from a vector<Instruction>*. Initialize it from vector<Instruction> or change the declaration to a pointer. If you go down the second route, you need to observe the rule of three.
You might also want to get a decent C++ book from this list.
Also, I think you have a using namespace std; in your header which is bad.
Do not use new in C++ unless you know what you are doing. (Which you do not, currently.)
Instead use automatic objects. You already defined instructions to be an automatic object. You just need to init it as if it were one:
class wrgxl {
public:
wrgxl()
: instructions() // this initializes the vector using its default constructor
{
// nothing needed here
}
...
private:
vector<Instruction> instructions;
...
};
The initialization of instructions in the constructor's initialization list is optional, though, if you only want to call the default constructor anyway. So in this case, this would be enough:
wrgxl()
{
}
If you wanted to dynamically allocate a vector, you would need to make instructions a pointer to a vector. But this rarely ever make sense, since the vector already allocates its data dynamically, but wraps this, so you do not have to deal with the ugly details resulting from this.
One of those details is that, if you have a dynamically allocated object in a class, you will then have to worry about destruction, copy construction, and copy assignment for that class.
As Kerrek already pointed out, you will need to have a good C++ book in order to properly learn C++. Make your pick.
I think you are confusing C++'s with C#'s syntax.
First, unlike in many languages, variables allocated on the stack (such as yours), are initialized by calling the default constructor, so I suspect that what you are doing is unnecessary.
Second, in order to do what you are trying to do, you use the following syntax:
instructions = vector<Instruction>();
however, as I said, this is likely redundant (and wasteful on a non-optimizing compiler as it might call both the constructor and the assignment operator). A much better way to do this is found in sbi's answer.
Third, unlike in C#, the new operator allocates memory on the heap and returns a pointer to the newly allocated data. Your variable instructions is not a pointer, thus the error.