From this question, I implement like this
Utils.h:
template<class T>
void SafeDeleteWithoutClass(T* &pVal) {
std::cout << __FUNCTION__ << std::endl;
delete pVal;
pVal = nullptr;
}
template<class T>
void SafeDeleteArrayWithoutClass(T* &pVal) {
std::cout << __FUNCTION__ << std::endl;
delete[] pVal;
pVal = nullptr;
}
main.cpp
#include "Utils.h"
struct Foo {
Foo() {std::cout << __FUNCTION__ << std::endl;}
~Foo() {std::cout << __FUNCTION__ << std::endl;}
}
int main()
{
Foo *pObj = new Foo();
SafeDeleteWithoutClass<Foo>(pObj2);
return 0;
}
It works well. But some guys in my team said it is not really better than macro. I don't know whether any example to prove this way is better than macro. Could you give me a hint?
It is not better then macro because you have no guarantee that it will save you from using pointer after deletion and deleting all things. It work practically the same. I guess that these guys just think it not better because it is the same. It is just written without using macro that's all.
Only advantage here is that you print some information on std::cout (but you can still do this in macro). And there are many disadventages here, to name few:
You can forget to call this function and have memory leak
Some one can still use pointer after it was deleted
It is hard to find if only one small object is leaking
You can call wrong function (e.g delete array for regular pointer)
Better to use std::shared_ptr<T> and std::unique_ptr. They will keep managing memory and make it clear who is the owner of memory (and memory ownership is important thing to consider on design of a class or whole project). But remember that smart pointers are not some miracle thing, you can still mess up some things. Take a look at this article to find out what not to do with them Top 10 dumb mistakes to avoid with C++ 11 smart pointers
Related
This was a question asked to me in an interview...
Is it possible to change the vtable memory locations after it's
created via constructor? If yes, is it a good idea? And how to do that?
If not, why not?
As i don't have that in depth idea about C++, my guess is that, it's not possible to change vtable after it's created!
Can anyone explain?
The C++ standards do not tell us how dynamic dispatch must be implemented. But vtable is the most common way.
Generally, the first 8 bytes of the object is used to store the pointer to vtable, but only if the object has at least 1 virtual function (otherwise we can save this 8 bytes for something else). And it is not possible to change the records in the vtable during run-time.
But you have memset or memcpy like functions and can do whatever you want (change the vtable pointer).
Code sample:
#include <bits/stdc++.h>
class A {
public:
virtual void f() {
std::cout << "A::f()" << std::endl;
}
virtual void g() {
std::cout << "A::g()" << std::endl;
}
};
class B {
public:
virtual void f() {
std::cout << "B::f()" << std::endl;
}
virtual void g() {
std::cout << "B::g()" << std::endl;
}
};
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
A * p_a = new A();
B * p_b = new B();
p_a->f();
p_a->g();
p_b->f();
p_b->g();
size_t * vptr_a = reinterpret_cast<size_t *>(p_a);
size_t * vptr_b = reinterpret_cast<size_t *>(p_b);
std::swap(*vptr_a, *vptr_b);
p_a->f();
p_a->g();
p_b->f();
p_b->g();
return 0;
}
Output:
A::f()
A::g()
B::f()
B::g()
B::f()
B::g()
A::f()
A::g()
https://ideone.com/CEkkmN
Of course all these manipulations is the way to shoot yourself in the foot.
The proper response to that question is simple: This question can't be answered. The question talks about the "vtable memory locations" and then continues with "after it's created via constructor". This sentence doesn't make sense because "locations" is plural while "it" can only refer to a singular.
Now, if you have a question concerning the typical C++ implementations that use a vtable pointer, please feel free to ask. I'd also consider reading The Design and Evolution of C++, which contains a bunch of background infos for people that want to understand how C++ works and why.
I am having trouble understanding proper usage of the new keyword. My question is:
Is the following just bad design as I suspect?
If not, where should I call delete?
If so, what is the better practice?
#include <string>
#include <iostream>
struct myOptions {
int myInt;
std::string myString;
};
myOptions* packageOptions() {
myOptions* options = new myOptions;
options->myInt = 42;
options->myString = "hello world";
return options;
}
int main() {
myOptions* options = packageOptions();
std::cout << options->myString << std::endl;
std::cout << options->myInt << std::endl;
delete myOptions; // this just feels wrong to put here
}
My gut is telling me it's bad because the main function shouldn't have to manage the memory allocated by other functions, as in it's breaking some kind of encapsulation. I thought about doing a class constructor/deconstructor, but that seems to be overkill.
There is no reason to have to chase around memory manually as you are doing. I would just declare your variable on the stack, and return it by value. Then let RAII clean up the memory for you when the variable falls out of scope.
myOptions packageOptions() {
myOptions options;
options.myInt = 42;
options.myString = "hello world";
return options;
}
int main() {
myOptions options = packageOptions();
std::cout << options.myString << std::endl;
std::cout << options.myInt << std::endl;
}
The delete keyword should only appear inside the implementation of smart pointer classes. You can either return by value as Cyber suggested, or in cases where that isn't ideal (for example, return by value causes slicing of derived types) you can return std::unique_ptr and store it in a local variable of the same type, and the destructor will automatically clean up the object and its memory when the pointer goes out of scope.
"Doing a class constructor/destructor" for each case would be overkill. Just take advantage of the existing highly reusable smart pointers.
From a strictly technical perspective, what you are doing is fine.
But you asked what the proper use of new is [in C++] -- and the answer may surprise you.
The most proper way to use new is not to. The same can be said of delete. Instead of using new/delete, you should be using smart pointers such as std::shared_ptr along with an accompanying make_shared.
I'm not saying there are no exceptions, but those exceptions would be unusual and typically the result of a design that could be otherwise modified.
In fact, I would also suggest another question altogether: what is the proper use of dynamic allocation? Again, the answer I would suggest is don't use dynamic allocation. Obviously there are exceptions to this as well, in fact more exceptions than the "don't use new" guideline above -- but as you become more experienced both with the syntax and the semantics of the C++ language, you will find that dynamic allocation is needed in fewer scenarios.
Using shared_ptr is not the best option in your present case. I give this example to show you it exists, and then you don't have to bother about who/when the object is deleted. The shared_ptr will call the destructor/delete whenever there are no references on the object left, ie at the end of main in your example. (also shared_ptr has been introduced in C++11, not available in C++03)
#include <string>
#include <iostream>
#include <memory>
struct myOptions {
int myInt;
std::string myString;
};
using OptionsPtr = std::shared_ptr<myOptions>;
OptionsPtr packageOptions() {
OptionsPtr options = std::make_shared<myOptions>();
options->myInt = 42;
options->myString = "hello world";
return options;
}
int main() {
OptionsPtr options = packageOptions();
std::cout << options->myString << std::endl;
std::cout << options->myInt << std::endl;
}
Anyway, in your case, stack allocation, like in #Cyber answer, is much preferable.
Instead of using structures in this manner, try to use classes and constructors/destructors for the same.
What you have demonstrated is correct as far as managing the memory goes. But stylistically and from a maintenance point of view, it could be much better.
Two ways that are easier to maintain are:
using smart pointers
Redesigning your code so that you pass in a structure to optionsPackage, allowing the function to populate the passed in structure, and the called to worry about the lifespan and usage of the structure.
Smart pointers were created to help prevent memory leaks, which can be a long term pain to find in large projects. Look into std::shared_ptr or see the shared pointers suggested answers.
Passing in the actual structure allows the caller to worry about the memory space used, including allocating and deallocating it. This was the preferred way, before smart pointers came along, and is still the rule of thumb (letting the code that needs the data manage the data object associated with it).
Passing in the actual structure would make the code look something like this:
#include <string>
#include <iostream>
struct myOptions {
int myInt;
std::string myString;
};
void packageOptions( myOptions& theInputOptions) {
theInputOptions.myInt = 42;
theInputOptions.myString = "hello world";
}
int main() {
myOptions options;
packageOptions( options );
std::cout << options.myString << std::endl;
std::cout << options.myInt << std::endl;
}
I find this style far easier to maintain the code. It can be combined with smart pointers where needed.
I got some weird problem. I use delete operator inside of class method and I want to know how solve this problem.
This is code:
#include <iostream>
using namespace std;
class A
{
public:
int a;
~A() {
cout << "call ~A()" << endl;
}
void action()
{
/* code here */
delete this; //this line depends on some if statements
/* code here */
}
void test2() {
cout << "call test2()" << a << endl;
}
void test() {
a = 10;
cout << "call test()" << endl;
action();
//how can I check if data is deleted?
test2();
}
};
int main()
{
A* a = new A();
a->test();
}
How can I check if data is deleted by delete operator?
Is it even possible?
Using delete this; is nearly always "bad". There are exceptions, but those are really unusual. Think about what you are trying to do. Most of the time, this means that you should have a wrapper object and an inner object that is created/deleted by the wrapper object.
You can't check if something has been deleted (in a reliable way/portable way). In your particular test-case, you are exercising "undefined behaviour" by "using an object after it has been destroyed", which means you can't really tell what is going to happen. You have to trust the C++ runtime that delete does what it says on the label.
In C++ there are other return values available than void. Therefore your action can return something that indicates if this has been deleted or not.
Note that you should not access any non-static data members or call any non-static member functions after deleteing this. Some people feel it to be difficult to guarantee so they ban delete this altogether.
Note to opponents that C++ FAQ claims that delete this is legal construct and I haven't also found anything forbidding it.
Working on a game in Cocos2d-x. I have CCLayers* and lots of CCSprites* that are created. I add these CCSprites in a std::vector after I create them.
My concern is memory and deleting.
I am trying to wrap my head around std::unique_ptr. My understanding is that smart pointers will help and clean up memory and prevent leaks.
But I dont understand how to use it. Do I make a unique_ptr out of every CCSPrite*? Do I make a unique_ptr and put my whole vector in it?
Can anyone help me understand and give me an idea what to brush up on?
Wherever you use new currently, make sure the result is immediately go to ctor of a unique_ptr, or its reset() function. And that smart pointer is placed so it will live where needed. Or you may pass the controlled object ahead to a different instance. Or nuke it using reset().
Vectors you don't usually allocate with new, so they are not subject to smart pointering: the vector itself manages the memory for the content, you're ahead by that.
Simplistically unique_ptr<T> is a wrapper class for a member T* p. In unique_ptr::~unique_ptr it calls delete p. It has a deleted copy constructor so that you don't accidentally copy it (and hence cause a double deletion).
It has a few more features, but that is basically all it is.
If you are writing a performance-critical game, it is probably a better idea to manage memory manually with some sort of memory-pool architecture. That isn't to say that you can't use a vector<unique_ptr<T>> as part of that, just to say that you should plan out the lifetime of your dynamic objects first, and then decide what mechanism to use to delete them at the end of that lifetime.
Cocos2d-x objects have own reference counter, and they use autorelease pool. If you will use std::unique_ptr, you should manually remove created object from autorelease pool and than register it in unique_ptr. Prefer to use CCPointer: https://github.com/ivzave/cocos2dx-ext/blob/master/CCPointer.h
If you need a polymorphic container, that is a vector that can hold CCSprites or any derived class, then you can use a std::vector<std::unique_ptr<CCSprite>> to describe this and provide you with you with lifetime management of the classes.
#include <memory>
#include <vector>
#include <iostream>
using namespace std;
class Foo {
int m_i;
public:
Foo(int i_) : m_i(i_) { cout << "Foo " << m_i << " ctor" << endl; }
~Foo() { cout << "Foo " << m_i << " ~tor" << endl; }
};
class FooBar : public Foo {
public:
FooBar(int i_) : Foo(i_) { cout << "FooBar " << m_i << " ctor" << endl; }
~FooBar() { cout << "FooBar " << m_i << " ~tor" << endl; }
};
int main(int argc, const char** argv) {
vector<unique_ptr<Foo>> foos;
Foo foo(1);
foos.emplace_back(unique_ptr<Foo>(new Foo(2)));
cout << "foos size at end: " << foos.size() << endl;
return 0;
}
(I tried adding an example of a short scoped unique_ptr being added to the vector but it caused my GCC 4.7.3 to crash when testing)
Foo 1 ctor
Foo 2 ctor
foos size at end: 1
[<-- exit happens here]
Foo 1 dtor
Foo 2 dtor
If you don't need a polymorphic container, then you can avoid the memory management overhead by just having the vector directly contain the CCSprite objects. The disadvantage to this approach is that the address of given sprites can change if you add/remove elements. If the object is non-trivial this can quickly get very expensive:
std::vector<CCSprite> sprites;
sprites.emplace_back(/* args */);
CCSprite* const first = &sprites.front();
for (size_t i = 0; i < 128; ++i) {
sprites.emplace_back(/* args */);
}
assert(first == &sprites.front()); // probably fires.
Programmers using boost::shared_ptr need to avoid cycles so that a resource leak is not created. The general advice is to use a boost::weak_ptr in the cases where such a cycle might be created. However doing so creates a gap in intention where one might have preferred to use a shared_ptr but didn't do so only because of the cycle problem.
It seems to me, though, that it should be possible to create a special kind of shared_ptr which avoids the cycle problem by linking the reference count of all the pointers in the cycle. And since I can think of a way to do it, I'm wondering does such a thing exists.
For the sake of proving that I'm not crazy, or perhaps that I am, I offer the following poorly thought out and ugly proof of concept:
#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
#include <boost/shared_ptr.hpp>
#include <iostream>
template <typename T>
struct shared_count_ptr
{
boost::shared_ptr<T> innerPtr;
template <typename TT>
void link( boost::shared_ptr<T> & sharedPtr, boost::shared_ptr<TT> & linked )
{
innerPtr = sharedPtr;
innerPtr.pn = linked.pn;
}
};
struct Hand;
struct Arm
{
Arm() { std::cout << "Creating Arm\n"; }
~Arm() { std::cout << "Destroying Arm\n"; }
shared_count_ptr<Hand> hand;
};
struct Hand
{
Hand() { std::cout << "Creating Hand\n"; }
~Hand() { std::cout << "Destroying Hand\n"; }
shared_count_ptr<Arm> arm;
};
int main()
{
boost::shared_ptr<Arm> savedArm;
std::cout << "Scope 0 entered\n";
{
std::cout << "\tScope 1 entered\n" ;
boost::shared_ptr<Arm> arm( new Arm );
{
std::cout << "\t\tScope 2 entered\n";
boost::shared_ptr<Hand> hand( new Hand );
hand->arm.link( arm, arm->hand );
arm->hand.innerPtr = hand;
savedArm = arm;
}
std::cout << "\t\tScope 2 exited\n";
}
std::cout << "\tScope 1 exited\n";
std::cout << "\tScope 0 about to exit\n";
return 0;
}
The general concept being that in the eyes of the imaginary shared_count_ptr, the Arm and Hand are the effectively same object.
So:
Does such a think already exist in boost?
If not, is it because it's a terrible idea? (Or did I just come up with something clever?)
Here's a simple test. Create a complete graph on 17 vertices, such that the program points only to vertex 0. Start removing edges at random. Does your idea work? (Spoiler: it doesn't).
I would imagine you could do something along those lines. However, in such a structure every pointer A needs to be aware about every single other pointer B, such that either B can be reached from A or vice versa. I don't see how this can possibly scale to more than a tiny number of interconnected pointers.
It would seem that if you want to support circular references without any help from the programmer, you more or less need a full-blown garbage collector rather than a simple reference counting scheme (I'd love to be proved wrong on this).