c++ new instance in function - c++

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.

Related

How to use shared_ptr to manage an object placed with placement new?

A fairly common thing I need to do is allot an object and some memory it'd like, in a strictly contagious region of memory together:
class Thing{
static_assert(alignof(Thing) == alignof(uint32), "party's over");
public:
~Thing(){
//// if only, but this would result in the equivalent of `free(danglingPtr)` being called
//// as the second stage of shared_ptr calling `delete this->get()`, which can't be skipped I believe?
// delete [] (char*)this;
}
static Thing * create(uint32 count) {
uint32 size = sizeof(Thing) + sizeof(uint32) * count; // no alignment concerns
char * data = new char[size];
return new (data)Thing(count);
}
static void destroy(Thing *& p) {
delete [] (char*)p;
p = NULL;
}
uint32 & operator[](uint32 index) {
assert(index < m_count);
return ((uint32*)((char*)(this + sizeof(Thing))))[index];
}
private:
Thing(uint32 count) : m_count(count) {};
uint32 m_count;
};
int main(){
{
auto p = shared_ptr<Thing>(Thing::create(1));
// how can I tell p how to kill the Thing?
}
return 0;
}
In Thing::Create() this is done with placement new into a section of memory.
I'd also like to have a shared pointer manage it in this case, using auto p = shared_ptr<Thing>(Thing::create(1)). But If it calls the equivalent of delete p.get() when the ref count empties, that'd be undefined as it mismatches the type and, more importantly, mismatches plural new with singular delete. I need it to delete in a special way.
Is there a way to easily set that up without defining an outside function? Perhaps by having the shared pointer call Thing::destroy() when the ref count empties? I know that shared pointer can accept a "deleter" as a template argument, but I'm unsure how to use it, or if it's even the proper way to address this?
std::shared_ptr accepts a deleter function as a second parameter, so you can use that to define how the managed object will be destroyed.
Here's a simplified example:
class Thing
{
public:
~Thing()
{
std::cout << "~Thing\n";
}
static std::shared_ptr<Thing> create() {
char * data = new char[sizeof(Thing)];
Thing* thing = new (data) Thing{};
return std::shared_ptr<Thing>{thing, &Thing::destroy};
}
static void destroy(Thing* p) {
p->~Thing();
delete [] (char*)p;
}
};
int main()
{
auto p = Thing::create();
}
Live Demo

Smartpointers equivalent

There is an equivalent codification in C++ with smartpointers for this code?
In External.cpp:
class ExampleClass {...};
ExampleClass* function()
{
ExampleClass *ptr = new ExampleClass();
ptr->doSomething();
return ptr;
}
In Another.cpp i would like to do something like this properly, how?:
ExampleClass *ptr2 = function();
There are two actually, you could use either unique_ptr or shared_ptr, look here when to use which: Which kind of pointer do I use when?
I'f you'd opt for the unique_ptr, then you'd get:
class ExampleClass {...};
std::unique_ptr<ExampleClass> function()
{
std::unique_ptr<ExampleClass> uptr = std::make_unique<ExampleClass>();
uptr->doSomething();
return std::move(uptr);
}
//In Another.cpp
std::unique_ptr<ExampleClass> ptr2 = function();
//you could even store the result in a shared pointer!!
std::shared_ptr<ExampleClass> ptr3 = function();
I won't really recommend it, but you can return an object that implicitly converts to a raw pointer. It will own it for a short duration, and delete if no-one grabs it.
struct RelinquishOrDelete {
ExampleClass *_ptr;
operator ExampleClass*() { auto ret = _ptr; _ptr = nullptr; return ret; }
~RelinquishOrDelete() {
if(!_ptr) {
cerr << "returned object wasn't taken by a new owner\n";
delete _ptr;
}
}
};
Using it is simple. It will pack and unpack the pointer in this simple case:
RelinquishOrDelete function()
{
ExampleClass *ptr = new ExampleClass();
ptr->doSomething();
return {ptr};
}
// ...
ExampleClass *ptr2 = function();
But of course, it will likely cause unexpected behavior if used in this perfectly reasonable piece of code:
auto ptr3 = function();
A smart pointer with much stricter ownership semantics is really the best approach.

Calling delete on C API to C++ interface segfaults with debug build

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

C++ set a pointer of pointer to null?

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.

c++ vector losing pointer reference

I should get the same in both lines..
what happen I get two different values.. like it was aiming to different positions..
I think the error is inside the d->add(*b)
the output is
thiago 14333804
Ph¿├┌ 2816532
to describe it better I put the code below
I got a program
int main(int argc, char **argv) {
CClass* c = new CClass();
BClass* b = c->getNext();
printf("%s %d \n", b->getValue(), b->getValue());
DClass* d = new DClass();
d->add(*b);
printf("%s %d \n", d->getNext(), d->getNext());
cin.get();
return 0;
}
the interfaces are below
class BClass
{
private:
char* value;
bool stale;
public:
BClass(char* value);
~BClass(void);
char* getValue();
bool isStale();
};
class CClass
{
private:
vector<BClass*> list;
public:
CClass(void);
~CClass(void);
BClass* getNext();
};
class DClass
{
private:
vector<BClass*> list;
static bool isStale(BClass* b) { return b->isStale();};
public:
DClass(void);
~DClass(void);
void add(BClass s);
char* getNext();
};
and the implementation follows
//BClass
BClass::BClass(char* value)
{
this->value = value;
this->stale = false;
}
BClass::~BClass(void)
{
}
char* BClass::getValue()
{
return value;
}
bool BClass::isStale()
{
return stale;
}
//CClass
CClass::CClass(void)
{
list.push_back(new BClass("thiago"));
list.push_back(new BClass("bruno"));
list.push_back(new BClass("carlos"));
}
CClass::~CClass(void)
{
}
BClass* CClass::getNext()
{
return list.at(0);
}
//DClass
DClass::DClass(void)
{
}
DClass::~DClass(void)
{
}
void DClass::add( BClass s )
{
list.push_back(&s);
}
char* DClass::getNext()
{
BClass* b = list.at(0);
return b->getValue();
}
When you pass in an instance of class B into D::add() function you create a deep copy of the object and that copy is what is put on stack. Later on you use the address of that copy to push it into list. Once the function is done this automatic variable goes out of scope thus the pointer you used to put into list is no longer valid.
To fix change your interface to avoid deep copies as follows:
void DClass::add( BClass * s )
{
list.push_back(s);
}
Step-by-step of what your code is doing
BClass* b = c->getNext(); // you get the address of the first element from the list (created in constructor) and assign it to b
d->add(*b); // the *b will dereference the object pointed to by b and put it onto stack in preparation to the call to add()
void DClass::add( BClass s ){ // the deep copy of a dereferenced object is put into this function's stack frame
list.push_back(&s); // an address of that temporary copy of the original object is being used to be added to your list
} // this is where the fun happens - once the function is done it will unwind the stack back up and the memory, previously occupied by that temp copy, will be re-used for other purposes. In your case - it will be used to pass parameters to functions d->getNext() (there's always a hidden this parameter to non-static member functions) and later to the printf() function. Remember - your previous pointer to that temp copy is still pointing to the stack, but it's now occupied by different data, causing you to see corruption
General rule of thumb - never use pointers to temp objects ;-)
in the DClass::add function, BClass s is a local variable.
void DClass::add( BClass s )
{
list.push_back(&s);
}
When you call d->add(*b);, you're passing a BClass by value, meaning you're creating a copy of it, and the address of that copy is not the same address of the original.
s will go out of scope as soon as the function returns, and the pointer to it will be invalid. So storing that pointer is no good to you, since dereferencing it would be undefined behaviour.