I'm having an issue where I have some code that wraps a C++ class, like the following:
C++:
class A
{
A() {}
~A() {}
}
C Interface:
typedef struct c_a c_a;
void c_a_new(c_a * self)
{
self = reinterpret_cast<c_a *>(new A());
}
void c_a_delete(c_a * self)
{
delete reinterpret_cast<A*>(self);
}
C Code:
c_a * self;
c_a_new(self);
c_a_delete(self);
I am building with gcc using CMake as a build system. Everything is fine when CMAKE_BUILD_TYPE is set to Release or RelWithDebInfo, but I get a segfault on calling c_a_delete(self); when it is set to Debug. This seems to occur on all of my classes with the C interface. If I comment out the delete call in c_a_delete(), it seems to fix that case. I imagine this may result in a memory leak though. Is there any chance the compiler might be optimizing the memory usage in the release builds or is something else going on?
You're passing pointer by value and you're not updating the original. Use return values or pointers to pointers. (I also added an additional handle typedef to make this more in sync with other C apis)
typedef struct c_a c_a, *a_handle;
void c_a_new(a_handle* self)
{
*self = reinterpret_cast<a_handle>(new A());
}
void c_a_delete(a_handle self)
{
delete reinterpret_cast<A*>(self);
}
and then call
a_handle self;
c_a_new(&self);
c_a_delete(self);
Or just return the acquired pointer:
typedef struct c_a c_a, *a_handle;
a_handle c_a_new(a_handle* self)
{
return reinterpret_cast<a_handle>(new A());
}
void c_a_delete(a_handle self)
{
delete reinterpret_cast<A*>(self);
}
and use it like this:
a_handle self = c_a_new();
c_a_delete(self);
If you want modification to an int to be visible outside of a function, one way is to pass a pointer to the the int, for example:
void foo(int * i) {
*i = 42;
}
so that the following holds:
int i = 1;
foo(&i);
assert(i == 42);
Similarly, if you want modification to c_a * to be visible outside of a function, one way is to pass a pointer to it, for example:
void c_a_new(c_a ** pself)
{
*pself = new A;
}
and call it as
c_a * self = NULL;
c_a_new(&self);
IMHO, design wise it is better to return the pointer instead of passing it by pointer and updating, i.e. something like
c_a * c_a_new()
{
return new (std::nothrow) A;
}
Lets say I have the following:
int main() {
int* test = new int;
*test = 5;
int* test2 = test;
}
Then, somewhere, in some function , I deallocate memory for test2 and set it to NULL. Is there a way to set test to NULL, in the same function without passing it to the function?
EDIT: std::shared_ptr cannot be used
The shared_ptr and weak_ptr classes do exactly what you want. Since you can't use them, your best option is to re-implement just the portions of them that you need. I'm going to assume you don't need any thread safety and that you don't care about optimizations for simplicity. If you do, use the standard library.
You need a control object. It should have a pointer to the real object and two integers, one the count of strong pointers, the other the count of weak pointers. Strong pointers and weak pointers should have a pointer to the control object.
When a strong pointer is destroyed, decrement the strong pointer count. If the strong pointer count is zero, delete the object and set its pointer to NULL. If the weak pointer count is also zero, discard the control object.
When a weak pointer is destroyed, decrement the weak pointer count. If both pointers counts are zero, discard the control object.
When pointers are copied, you must bump the count. When a weak pointer is promoted to a strong pointer, bump the strong pointer count and fail the operation if it was previously zero.
That should be enough to give you the idea.
Pass the pointer be reference, since a copy would be passed to the function had you used a normal pointer, on which you can only change the pointed value, and since both pointers point to the same thing, no need to call change() on both:
#include <iostream>
void change(int*& p)
{
delete p;
p = nullptr;
}
int main()
{
int* test = new int;
*test = 5;
int* test2 = test;
std::cout << *test; //5
std::cout << *test2; //5
change(test);
}
Example
BTW, I recommend std::shared_ptr for a purpose like this, or std::unique_ptr
EDIT
The only problem above is that test2 is deleted, not pointing to nullptr, but that cannot be changed unless with smart pointers or a different function.
By default, when you pass a pointer to a function, you are passing a copy of the value:
void f(int* p) {
// p has the same value as x below, but is independent
delete p;
p = nullptr;
// p is null, but back in main 'x' still has the original value
}
int main() {
int* x = new int;
f(x);
// 'x' is unmodified and now points to a deleted block of memory
}
Your options are to pass the pointer by reference or pass a pointer to the pointer:
#include <iostream>
void by_pointer(int** p) {
delete *p;
*p = nullptr;
}
void by_reference(int*& p) {
delete p;
p = nullptr;
}
int main() {
int* x = new int;
by_pointer(&x);
std::cout << (void*)x << "\n"; // outputs null
int* y = new int;
by_reference(y);
std::cout << (void*)y << "\n"; // outputs null
}
If you really want this (though I'd strongly suggest you to reconsider your design), then the following might work for you:
We wrap the pointer in a structure/class to be able to "hook" us on construction and destruction of such pointers:
template<typename T>
struct pointer {
Since when freeing the stored value, we also need to modify all pointers that still point to it, we need to keep track of them somehow. I'd say just store them alongside the value:
struct boxing {
T value;
std::set<pointer<T> *> references;
};
boxing * box;
Next comes constructing a pointer. I simplified here. You might want to add perfect forwarding, a possibility to construct a "null pointer", and so on ...
pointer(T value) : box(new boxing{value}) {
add_myself();
}
As you see, we "add ourselves" (to the set of references). When the pointer is destructed, we need to remove ourselves from that set again:
~pointer() {
remove_myself();
}
When being copy constructed, we just use the box from the original and add ourselves:
pointer(pointer const & p) : box(p.box) {
add_myself();
}
When being copy assigned to, we first need to remove ourselves from the current box, use the box of the original and add ourselves:
pointer & operator=(pointer const & p) {
remove_myself();
box = p.box;
add_myself();
}
I'm lazy. Implement move construction / assignment yourself ;)
pointer(pointer &&) = delete;
pointer & operator=(pointer &&) = delete;
We want to be able to use the pointer, so we add a conversion operator to a raw pointer:
operator T*(void) {
return box ? &(box->value) : nullptr;
}
Finally, freeing a pointer. We set all box members of the current pointers in the references set to nullptr (this includes ourself, thus the additional pointer b), and then delete the box:
void free() {
boxing * b = box;
for (pointer * p : b->references) {
p->box = nullptr;
}
delete b;
}
Oh, and last but not least, adding and removing ourselves:
private:
void remove_myself() {
if (box == nullptr) return;
box->references.erase(this);
if (box->references.size() == 0) {
delete box;
}
}
void add_myself() {
if (box == nullptr) return;
box->references.insert(this);
}
};
Some function. Note that I pass by value to force another copy construction:
void foo(pointer<int> p) {
p.free();
}
Two pointers, pointing to the same boxed value:
int main(int, char **) {
pointer<int> a{21};
pointer<int> b = a;
*b = 42;
std::cout << *a << std::endl;
foo(a);
std::cout << "a is " << ((a == nullptr) ? "null" : "non-null") << std::endl;
return 0;
}
Above example on ideone.
The idea of shared controllers of a uniquely-owned object is of course horrid (for reasons that will become clear).
Nevertheless, it can be done:
template<class T, class Deleter = std::default_delete<T>>
struct shared_unique
{
struct control_block
{
control_block(Deleter del, T* p) : del_(std::move(del)), ptr_(p), refs_(1) {}
Deleter del_;
T* ptr_;
std::size_t refs_;
void addref()
{
++refs_;
}
void release()
{
if (--refs_ == 0)
delete this;
}
~control_block() {
if (ptr_)
del_(ptr_);
}
};
control_block* ctrl_;
shared_unique(T* p = nullptr, Deleter del = Deleter()) : ctrl_(new control_block(std::move(del), p)) {}
shared_unique(shared_unique const& r) : ctrl_(r.ctrl_) { ctrl_->addref(); }
shared_unique& operator=(shared_unique const& r)
{
auto tmp = r;
swap(r);
return *this;
}
shared_unique(shared_unique&& r) : ctrl_(r.ctrl_) { r.ctrl_ = nullptr; }
shared_unique& operator=(shared_unique&& r)
{
auto tmp = std::move(r);
swap(tmp);
return *this;
}
~shared_unique()
{
ctrl_->release();
}
void swap(shared_unique& r) noexcept
{
std::swap(ctrl_, r.ctrl_);
}
void reset(T* p = nullptr)
{
std::swap(ctrl_->ptr_, p);
delete p;
}
T* get() const {
return ctrl_->ptr_;
}
};
int main()
{
shared_unique<int> su1(new int(5));
assert( su1.get() );
assert( *(su1.get()) == 5 );
shared_unique<int> su2 = su1;
assert( su2.get() );
assert( *(su2.get()) == 5 );
su1.reset();
assert( su1.get() == nullptr );
assert( su2.get() == nullptr );
}
The problem is that it is impossible to make this arrangement thread-safe, unless you provide some kind of 'lock' mechanism to keep the pointed-to object alive while it's being accessed.
If you want to know when an object has been destroyed, it's probably better to have it (or its smart pointer) emit a signal when this happens and have the interested observers listen on the slot (or similar).
I have a question about delete and memory leak in C++. Considered the code below:
class AnObject{
public:
AnObject* Foo(){
// how can I delete this object ???
AnObject* obj = new AnObject();
...
return obj;
}
};
int main(){
...
AnObject* x = new AnObject();
AnObject* result = x->Foo();
delete x;
return 0;
}
My question is how can I delete the pointer in fuction AnObject::Foo() ???
// I read some suggestions who required changing the function, don't create an object with the word new in a fucntion. But does it exist a method to delete this pointer ?
You would do so by deleting this within AnObject::Foo but I would strongly discourage you from doing so. In this case, you do not need pointers at all:
class AnObject{
public:
AnObject Foo(){
return AnObject{};
}
};
int main()
{
AnObject x{};
AnObject result = x.Foo();
return 0;
}
If for whatever reason you really do need pointers, consider smart pointers
#include <memory>
class AnObject{
public:
std::unique_ptr<AnObject> Foo(){
return std::make_unique<AnObject>();
}
};
int main()
{
std::unique_ptr<AnObject> x = std::make_unique<AnObject>();
std::unique_ptr<AnObject> result = x->Foo();
return 0;
}
In both cases, you do not need to delete anything as you are using RAII semantics to handle your memory cleanup via scope.
I'm working on some kind of smart pointer technique but there is one piece I'm missing. I tried several combinations but the logic is as follow:
UInt *obj = new UInt;
UInt *ref;
ref = obj;
delete obj;
obj = NULL;
if (ref == NULL)
{
// It works
}
else
{
// It failed
}
Is there any way to hit "It Works" without setting ref to NULL explicitly?
EDIT:
A more appropriate scenario would be something like this:
class A
{
public:
A(): ref(NULL) {}
~A()
{
if (ref != NULL)
delete ref;
}
int *ref;
};
int *obj = new int;
A *host = new A();
host->ref = obj; ???
delete obj;
obj = NULL;
if (host->ref == NULL)
{
// It works.
}
else
{
// It failed.
}
...
Can't use int*& ref as a class member though.... must be close.
As you say, you should be using a smart pointer:
#include <memory>
std::shared_ptr<UInt> obj = std::make_shared<UInt>();
std::weak_ptr<UInt> ref = obj;
obj.reset();
if (ref.expired())
{
// It works
}
else
{
// It failed
}
Don't try managing your own memory when the standard library has facilities to do it for you.
Declare ref as a reference to pointer
Uint*& ref = obj;
ref will now refer to the obj pointer.
Intially both obj and ref point to the (same) UInt instance. Then you delete the instance and set obj to NULL. But ref is just like any other regular pointer, so it still points to the deleted instance.
Instead you can create a reference variable, or in this case a 'reference pointer' by adding & to the declaration:
Uint*& ref = obj;
Then ref really refers to obj and keeps the same value (pointer) as obj.
I have this problem:
void myFunc()
{
MyClass * myInstance = NULL;
newInstance(myInstance);
}
void newInstance(MyClass * instance)
{
instance = new MyClass(...);
}
the code seems to work fine, but when I exits from newInstance function, my myInstance is null and not with the values that have inside newInstance... where is the problem?t
thanks
The pointer is copied into newInstance and then you change the value of that copy. If you want to modify the pointer inside the function, you need to pass it by reference:
void newInstance(MyClass*& instance)
{
instance = new MyClass(...);
}
Or alternatively, you could pass a MyClass** and do *instance = new Class(...);.
Either way, it would be preferable to actually return the pointer instead of passing it as a modifiable argument.
void myFunc()
{
MyClass * myInstance = newInstance();
delete myInstance;
}
MyClass* newInstance()
{
return new MyClass(...);
}
Of course, you will have to remember to delete the object. To avoid this, you can make it safer by using smart pointers:
void myFunc()
{
auto myInstance = newInstance();
}
std::unique_ptr<MyClass> newInstance()
{
return std::unique_ptr<MyClass>(new MyClass(...));
}
You would need to pass a refetence to a pointer, or return the pointer from the function:
void newInstance(MyClass*& instance)
{
instance = new MyClass(...);
}
MyClass* newInstance()
{
return new MyClass(...);
}
But you don't want to deal with raw pointers to dynamically allocated memory. What you really need is to use smart pointers here, particularly std::unique_ptr.