I wrote the following code creating singleton instance of my interface manager.
#include <intrin.h>
#pragma intrinsic(_ReadWriteBarrier)
boost::mutex global_interface_manager_creation_mutex;
interface_manager* global_interface_manager = NULL;
interface_manager* get_global_interface_manager() {
interface_manager* volatile temp = global_interface_manager;
_ReadWriteBarrier();
if (temp == NULL) {
boost::mutex::scoped_lock(global_interface_manager_creation_mutex);
temp = global_interface_manager;
if (temp == NULL) {
temp = new interface_manager();
_ReadWriteBarrier();
global_interface_manager = temp;
}
}
return temp;
}
But I don't want to use the lock and memory barrier so change the code to:
interface_manager* get_global_interface_manager() {
interface_manager* volatile temp = global_interface_manager;
__assume(temp != NULL);
if (temp == NULL) {
temp = new interface_manager();
if(NULL != ::InterlockedCompareExchangePointer((volatile PVOID *)&global_interface_manager, temp, NULL)) {
delete temp;
temp = global_interface_manager;
}
}
return temp;
}
It seems like this code works well but I don't be sure and I really don't know how to test it is correct.
My question would be: Is it really, really, really necessary to make a threadsafe singleton?
Singletons are debatable, but they do have their uses (and I guess discussing those would be going far off-topic).
However, threadsafe singletons are something that is 99.99% of the time unnecessary and 99.99% of the time implemented wrong, too (even people who should know how to do it right have proven in the past that they got it wrong). So, I think that in this case "do you really need this" is a valid concern.
If you create an instance of your singleton at application startup, for example from within main(), there will be only one thread. That can be as easy as calling get_global_interface_manager() once, or calling yourlibrary::init() which implicitly calls get().
Any concerns about thread-safety are irrelevant as soon as you do this, as there will be forcibly only one thread at this time. And, you are guaranteed that it will work. No ifs and whens.
A lot of, if not all, libraries require you to call an init function at startup, so that is not an uncommon requirement, either.
Have you looked into using pthread_once? http://sourceware.org/pthreads-win32/manual/pthread_once.html
This is the use case it was made for.
#include <stddef.h> // NULL
#include <pthread.h>
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
static interface_manager* m;
static void* init_interface_manager()
{
m = new interface_manager;
return NULL;
}
interface_manager* get_global_interface_manager()
{
pthread_once(&once_control, &init_interface_manager);
return m;
}
One of the difficult parts of multi-threaded programming is that something might appear to work 99.9% of the time, then fail miserably.
In your case, there's nothing to prevent two threads from getting NULL back from the global pointer and both allocating new singletons. One will get deleted, but you'll still pass it back as the return value from the function.
I even had trouble convincing myself that my own analysis was correct.
You could fix it easily by returning global_interface_manager rather than temp. There's still the possibility of creating an interface_manager that you turn around and delete, but I assume that was your intention.
You could store the singleton as an atomic reference. After instantiating, CAS to set the reference. This will not guarantee that two copies don't get instantiated, only that the same one will always be returned from inst. Since standard C doesn't have atomic instructions I can show it in Java:
class Foo
{
static AtomicReference<Foo> foo = new AtomicReference<>();
public static Foo inst()
{
Foo atomic = foo.get();
if(atomic != null)
return atomic;
else
{
Foo newFoo = new Foo();
//newFoo will only be set if no other thread has set it
foo.compareAndSet(null, newFoo);
//if the above CAS failed, foo.get would be a different object
return foo.get();
}
}
}
Related
So, I have an array of a class called "Customer"
Customer** customersarray[] = new Customer*[customer];
I'm receiving int customer with cin.
anyways, in customer.cpp, there is a method called void deactivate().
which goes like this:
void Custmoer::deactivate()
{
if (this != NULL)
remove this;
//this = NULL; I want to do this but it doesn't work.
}
and the purpose of this is to remove it from customer array when satisfies a certain condition. So for example,
for (int i = customer - 1; i >= 0; i--)
{
if (customersarray[i]->getAngerLevel() == 5) {
customersarray[i]->deactivate();
}
for (int z = i; i < customer - 1; i++) {
*(customersarray + z) = *(customersarray + z + 1);
}
customer--;
}
so my first questions are:
why does this = NULL not work?
is there a simpler way to remove something from pointer array when a condition is satisfied? (for example, remove all customers that has anger level of 5.)
Your mistake is thinking that you can remove something from a Customer* array by some magic inside the Customer class, but that's not true. Just remove a customer from the customer array where ever the customer array is. For instance using remove_if
#include <algorithm>
Customer** customersarray = new Customer*[customer];
...
customer = std::remove_if(customersarray, customersarray + customer,
[](Customer* c) { return c->anger() == 5; }) - customersarray;
This updates the customer variable to be the new size of the array, but doesn't free or reallocate any memory. Since you are using dynamic arrays and pointers you are responsible for that.
Which is why you should really not be using pointers or arrays, but using vectors instead.
std::vector<Customer> customerVector;
Life will be so much simpler.
Type of "this" is a constant pointer which means you cant change where it points
Your function can return a boolean and if its true just set your pointer to null
You'll be much better off using a std::vector, all memory memory management gets much safer. You cannot modify the this pointer, but that would be meaningless anyway:
It is a local variable, so any other pointer outside would not be changed, not even the one you called the function on (x->f(): the value of x is copied into this).
It contains the address of the current object - the current object is at a specific memory location and cannot be moved away from (not to be mixed up with 'moving' in the context of move semantics!).
You can, however, delete the current object (but I don't say you should!!!):
class Customer
{
static std::vector<Customer*> customers;
public:
void commitSuicide()
{
auto i = customers.find(this);
if(i != customers.end())
customers.erase(i);
delete this;
}
}
Might look strange, but is legal. But it is dangerous as well. You need to be absolutely sure that you do not use the this pointer or any other poiner to the current object any more afterwards (accessing non-static members, calling non-static functions, etc), it would be undefined behaviour!
x->commitSuicide();
x->someFunction(); // invalid, undefined behaviour!!! (x is not alive any more)
Similar scenario:
class Customer
{
static std::vector<std::unique_ptr<Customer>> customers;
public:
void commitSuicide()
{
auto i = customers.find(this);
if(i != customers.end())
{
customers.erase(i); // even now, this is deleted!!! (smart pointer!)
this->someFunction(); // UNDEFINED BEHAVIOUR!
}
}
}
If handling it correctly, it works, sure. Your scenario might allow a much safer pattern, though:
class Customer
{
static std::vector<std::unique_ptr<Customer>> customers;
public:
Customer()
{
customers->push_back(this);
};
~Customer()
{
auto i = customers.find(this);
if(i != customers.end())
customers.erase(i);
}
}
There are numerous variations possible (some including smart pointers); which one is most appropriate depends on the use case, though...
First of all, attending to RAII idiom, you are trying to delete an object before using its destructor ~Customer(). You should try to improve the design of your Customer class through a smart use of constructor and destructor:
Customer() {// initialize resources}
~Customer() {// 'delete' resources previously created with 'new'}
void deactivate() {// other internal operations to be done before removing a customer}
Then, your constructor Customer() would initialize your internal class members and the destructor ~Customer() would release them if necessary, avoiding memory leaks.
The other question is, why do you not use another type of Standard Container as std::list<Customer>? It supports constant time removal of elements at any position:
std::list<Customer> customers
...
customers.remove_if([](Customer foo) { return foo.getAngerLevel() == 5; });
If you only expect to erase Customer instances once during the lifetime of the program the idea of using a std::vector<Customer> is also correct.
I am editing some code of an open source game and normally the code doesn't directly access the player or creature class; however its parameter Cylinder is at the top of the food chain when it comes to everything.
My question is should I be deleting all these pointers or setting them to NULL after I am done with them?
Here is the code I've written; it works fine but I don't want to crash the server over an issue such as a dangling pointer (still a bit new to C++).
bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
if (cylinder == nullptr) {
return false;
}
if (money == 0) {
return true;
}
if (Creature *creature = cylinder->getCreature()) {
if (Player *player = creature->getPlayer()) {
uint64_t cash = player->getBankBalance();
if (cash < money) {
return false;
}
player->setBankBalance(cash - money);
}
}
return true;
}
void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
if (Creature *creature = cylinder->getCreature()) {
if (Player *player = creature->getPlayer()) {
player->setBankBalance(player->getBankBalance() + money);
}
}
}
In general (and unless the documentation says otherwise), don't delete objects if you are passed a pointer. Assume that you are not being given ownership of the object.
Modern C++ helps you avoid needing to know whether you are being given ownership: you may be given a std::shared_ptr<Cylinder> or a std::unique_ptr<Cylinder> - either way, deletion is handled for you when the smart pointer goes out of scope. But often, you have to work with a library that doesn't give you such reassurance.
There's no need to null out any pointers used within a small scope (e.g. a function). If you keep pointer variables around for longer (in a member variable, perhaps), then it may help prevent accidents if you do so. As C++ is not a garbage-collected language, there's no benefit from nulling pointers that are about to go out of scope.
delete is only required if there is a call to new when you obtain the Cylinder object from the game. There probably isn't, but you need to check the code.
Setting to NULL is something that you do if the object pointed to has been (or is at risk of getting) deleted. This is only to ensure that the invalid pointer cannot be accidentally used some time later.
I've been having trouble understanding the delete and delete [] functions in C++. Here's what I know so far:
aClass *ptr = new aClass(); //Allocates memory on the heap for a aClass object
//Adds a pointer to that object
...
delete ptr; //ptr is still a pointer, but the object that it
//was pointing to is now destroyed. ptr is
//pointing to memory garbage at this point
ptr = anotehrOjbectPtr //ptr is now pointing to something else
In the case that this happens,
aClass *ptr new aClass();
...
ptr = anotherObjectPtr
the object that pointer was pointing to, is now lost in memory, adn this will cause a memory leak. The object should've been deleted first.
I hope the above is correct
But I wrote this small program, where I'm getting some unexpected behaviour
#include <iostream>
#include <string>
using namespace std;
class Database {
private:
Database() {
arrNames = NULL;
capacity = 1;
size = 0;
}
Database(const Database &db) {}
Database &operator=(const Database &db) {}
string *arrNames;
int capacity, size;
public:
static Database &getDB() {
static Database database;
return database;
}
void addName(string name) {
if (arrNames == NULL) {
arrNames = new string[capacity];
}
if (size == capacity - 1) {
capacity *= 2;
string *temp = new string[capacity];
int i = 0;
while (i <= size) {
temp[i] = arrNames[i];
i++;
}
delete [] arrNames;
arrNames = temp;
}
arrNames[size] = name;
size++;
}
void print() {
int i = 0;
while (i <= size) {
cout << arrNames[i] << endl;
i++;
}
}
};
int main() {
Database &database = Database::getDB();
Database &db = Database::getDB();
Database &info = Database::getDB();
database.addName("Neo");
db.addName("Morpheus");
info.addName("Agent Smith");
database.print();
db.print();
info.print();
}
In the addName function, when I call delete [] arrNames, what I think is happening is that the memory associated with the current array arrNames is destroyed, so arrNames is now pointing at garbage, Then arrNames is directed to point to another location in memory that is pointed to by temp. So if I hadn't called delete [] arrNames, then that location in memory would've been invalid, causing a memory leak. However, when I comment out that line, the code still works without problems. Am I not understanding something here?
Sorry that this si so long
Thanks for the halp
However, when I comment out that line, the code still works without problems. Am I not understanding something here?
An important thing to know about programming is that doing things correctly is not merely a matter of having things apparently work.
Often times you can try something out hand have things appear to work, but then some outside circumstances change, something you're not explicitly controlling or accounting for, and things stop working. For example you might write a program and it runs find on your computer, then you try to demo it to someone and happen to run it on their computer, and the program crashes. This idea is the basis of the running joke among programmers: "It works for me."
So things might appear to work, but in order to know that things will work even when conditions change you have to meet a higher standard.
You've been told how to do things correctly with delete, but that doesn't necessarily mean that things will break in an obvious way if you fail to do so. You need to abandon the idea that you can definitively determine whether something is correct or not by trying it out.
From what I think I see in your code, it looks like addName() is meant to append the new name onto the dynamic array. Doing this yourself can be headache inducing, and there is an existing convenient STL template for just this which I strongly recommend, called vector, from the <vector> header.
If you add #include <vector> and change string *arrNames to vector<string> arrNames, then your entire addName() function can be reduced to:
void addName(string name){
arrNames.push_back(name);
}
From the vector.size() method, you can determine the current length of the vector as well, and your members capacity and size are no longer needed.
A memory leak doesn't involve anything being made invalid. Quite the reverse, it's a failure to make a memory location invalid, causing it to remain in use even when it shouldn't be.
First of all, when you delete something, you are not destroying it in memory, just making it available for some further allocation. This is somewhat similar to filesystem - when you delete file, you just say space it occupied is now available for some new data. You could actually retrieve unmodified data after you called delete on them, but this is undefined behavior and will be compiler/OS specific.
If you don´t delete[] arrNames, you leave its data forgotten in your process´s memory, and creating memory leak. But beside this fatal flaw, there is no more magic happening.
Example:
bool isHeapPtr(void* ptr)
{
//...
}
int iStack = 35;
int *ptrStack = &iStack;
bool isHeapPointer1 = isHeapPtr(ptrStack); // Should be false
bool isHeapPointer2 = isHeapPtr(new int(5)); // Should be true
/* I know... it is a memory leak */
Why, I want to know this:
If I have in a class a member-pointer and I don't know if the pointing object is new-allocated. Then I should use such a utility to know if I have to delete the pointer.
But:
My design isn't made yet. So, I will program it that way I always have to delete it. I'm going to avoid rubbish programming
There is no way of doing this - and if you need to do it, there is something wrong with your design. There is a discussion of why you can't do this in More Effective C++.
In the general case, you're out of luck, I'm afraid - since pointers can have any value, there's no way to tell them apart. If you had knowledge of your stack start address and size (from your TCB in an embedded operating system, for example), you might be able to do it. Something like:
stackBase = myTCB->stackBase;
stackSize = myTCB->stackSize;
if ((ptrStack < stackBase) && (ptrStack > (stackBase - stackSize)))
isStackPointer1 = TRUE;
The only "good" solution I can think of is to overload operator new for that class and track it. Something like this (brain compiled code):
class T {
public:
void *operator new(size_t n) {
void *p = ::operator new(n);
heap_track().insert(p);
return p;
}
void operator delete(void* p) {
heap_track().erase(p);
::operator delete(p);
}
private:
// a function to avoid static initialization order fiasco
static std::set<void*>& heap_track() {
static std::set<void*> s_;
return s_;
}
public:
static bool is_heap(void *p) {
return heap_track().find(p) != heap_track().end();
}
};
Then you can do stuff like this:
T *x = new X;
if(T::is_heap(x)) {
delete x;
}
However, I would advise against a design which requires you to be able to ask if something was allocated on the heap.
Well, get out your assembler book, and compare your pointer's address to the stack-pointer:
int64_t x = 0;
asm("movq %%rsp, %0;" : "=r" (x) );
if ( myPtr < x ) {
...in heap...
}
Now x would contain the address to which you'll have to compare your pointer to. Note that it will not work for memory allocated in another thread, since it will have its own stack.
here it is, works for MSVC:
#define isheap(x, res) { \
void* vesp, *vebp; \
_asm {mov vesp, esp}; \
_asm {mov vebp, ebp}; \
res = !(x < vebp && x >= vesp); }
int si;
void func()
{
int i;
bool b1;
bool b2;
isheap(&i, b1);
isheap(&si, b2);
return;
}
it is a bit ugly, but works. Works only for local variables. If you pass stack pointer from calling function this macro will return true (means it is heap)
In mainstream operating systems, the stack grows from the top while the heap grows from the bottom. So you might heuristically check whether the address is beyond a large value, for some definition of "large." For example, the following works on my 64-bit Linux system:
#include <iostream>
bool isHeapPtr(const void* ptr) {
return reinterpret_cast<unsigned long long int>(ptr) < 0xffffffffull;
}
int main() {
int iStack = 35;
int *ptrStack = &iStack;
std::cout << isHeapPtr(ptrStack) << std::endl;
std::cout << isHeapPtr(new int(5)) << std::endl;
}
Note that is a crude heuristic that might be interesting to play with, but is not appropriate for production code.
First, why do you need to know this? What real problem are you trying to solve?
The only way I'm aware of to make this sort of determination would be to overload global operator new and operator delete. Then you can ask your memory manager if a pointer belongs to it (the heap) or not (stack or global data).
Even if you could determine whether a pointer was on one particular heap, or one particular stack, there can be multiple heaps and multiple stacks for one application.
Based on the reason for asking, it is extremely important for each container to have a strict policy on whether it "owns" pointers that it holds or not. After all, even if those pointers point to heap-allocated memory, some other piece of code might also have a copy of the same pointer. Each pointer should have one "owner" at a time, though ownership can be transferred. The owner is responsible for destructing.
On rare occasions, it is useful for a container to keep track of both owned and non-owned pointers - either using flags, or by storing them separately. Most of the time, though, it's simpler just to set a clear policy for any object that can hold pointers. For example, most smart pointers always own their container real pointers.
Of course smart pointers are significant here - if you want an ownership-tracking pointer, I'm sure you can find or write a smart pointer type to abstract that hassle away.
Despite loud claims to the contrary, it is clearly possible to do what you want, in a platform-dependent way. However just because something is possible, that does not automatically make it a good idea. A simple rule of stack==no delete, otherwise==delete is unlikely to work well.
A more common way is to say that if I allocated a buffer, then I have to delete it, If the program passes me a buffer, it is not my responsibility to delete it.
e.g.
class CSomething
{
public:
CSomething()
: m_pBuffer(new char[128])
, m_bDeleteBuffer(true)
{
}
CSomething(const char *pBuffer)
: m_pBuffer(pBuffer)
, m_bDeleteBuffer(false)
{
}
~CSomething()
{
if (m_bDeleteBuffer)
delete [] m_pBuffer;
}
private:
const char *m_pBuffer;
bool m_bDeleteBuffer;
};
You're trying to do it the hard way. Clarify your design so it's clear who "owns" data and let that code deal with its lifetime.
here is universal way to do it in windows using TIP:
bool isStack(void* x)
{
void* btn, *top;
_asm {
mov eax, FS:[0x08]
mov btn, eax
mov eax, FS:[0x04]
mov top, eax
}
return x < top && x > btn;
}
void func()
{
int i;
bool b1;
bool b2;
b1 = isStack(&i);
b2 = isStack(&si);
return;
}
The only way I know of doing this semi-reliably is if you can overload operator new for the type for which you need to do this. Unfortunately there are some major pitfalls there and I can't remember what they are.
I do know that one pitfall is that something can be on the heap without having been allocated directly. For example:
class A {
int data;
};
class B {
public:
A *giveMeAnA() { return &anA; }
int data;
A anA;
};
void foo()
{
B *b = new B;
A *a = b->giveMeAnA();
}
In the above code a in foo ends up with a pointer to an object on the heap that was not allocated with new. If your question is really "How do I know if I can call delete on this pointer." overloading operator new to do something tricky might help you answer that question. I still think that if you have to ask that question you've done something very wrong.
How could you not know if something is heap-allocated or not? You should design the software to have a single point of allocation.
Unless you're doing some truly exotic stuff in an embedded device or working deep in a custom kernel, I just don't see the need for it.
Look at this code (no error checking, for the sake of example):
class A
{
int *mysweetptr;
A()
{
mysweetptr = 0; //always 0 when unalloc'd
}
void doit()
{
if( ! mysweetptr)
{
mysweetptr = new int; //now has non-null value
}
}
void undoit()
{
if(mysweetptr)
{
delete mysweetptr;
mysweetptr = 0; //notice that we reset it to 0.
}
}
bool doihaveit()
{
if(mysweetptr)
return true;
else
return false;
}
~A()
{
undoit();
}
};
In particular, notice that I am using the null value to determine whether the pointer has been allocated or not, or if I need to delete it or not.
Your design should not rely on determining this information (as others have pointed out, it's not really possible). Instead, your class should explicitly define the ownership of pointers that it takes in its constructor or methods. If your class takes ownership of those pointers, then it is incorrect behavior to pass in a pointer to the stack or global, and you should delete it with the knowledge that incorrect client code may crash. If your class does not take ownership, it should not be deleting the pointer.
Consider the following c++ code:
class test
{
public:
int val;
test():val(0){}
~test()
{
cout << "Destructor called\n";
}
};
int main()
{
test obj;
test *ptr = &obj;
delete ptr;
cout << obj.val << endl;
return 0;
}
I know delete should be called only on dynamically allocated objects but what would happen to obj now ?
Ok I get that we are not supposed to do such a thing, now if i am writing the following implementation of a smart pointer, how can i make sure that such a thing does't happen.
class smart_ptr
{
public:
int *ref;
int *cnt;
smart_ptr(int *ptr)
{
ref = ptr;
cnt = new int(1);
}
smart_ptr& operator=(smart_ptr &smptr)
{
if(this != &smptr)
{
// House keeping
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
// Now update
ref = smptr.ref;
cnt = smptr.cnt;
(*cnt)++;
}
return *this;
}
~smart_ptr()
{
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
}
};
You've asked two distinct questions in your post. I'll answer them separately.
but what would happen to obj now ?
The behavior of your program is undefined. The C++ standard makes no comment on what happens to obj now. In fact, the standard makes no comment what your program does before the error, either. It simply is not defined.
Perhaps your compiler vendor makes a commitment to what happens, perhaps you can examine the assembly and predict what will happen, but C++, per se, does not define what happens.
Practially speaking1, you will likely get a warning message from your standard library, or you will get a seg fault, or both.
1: Assuming that you are running in either Windows or a UNIX-like system with an MMU. Other rules apply to other compilers and OSes.
how can i make sure that [deleteing a stack variable] doesn't happen.
Never initialize smart_ptr with the address of a stack variable. One way to do that is to document the interface to smart_ptr. Another way is to redefine the interface so that the user never passes a pointer to smart_ptr; make smart_ptr responsible for invoking new.
Your code has undefined behaviour because you used delete on a pointer that was not allocated with new. This means anything could happen and it's impossible to say what would happen to obj.
I would guess that on most platforms your code would crash.
Delete's trying to get access to obj space in memory, but opperation system don't allow to do this and throws (core dumped) exception.
It's undefined what will happen so you can't say much. The best you can do is speculate for particular implementations/compilers.
It's not just undefined behavior, like stated in other answers. This will almost certainly crash.
The first issue is with attempting to free a stack variable.
The second issue will occur upon program termination, when test destructor will be called for obj.