Safe Delete in C++ - c++

I have developed an array based implementation of a hashTable with several stock names, symbols, prices, and the like. I need to remove a stock from my array. I am told that using the delete operator is bad object oriented design. What is the good object oriented design for deletion?
bool hash::remove(char const * const symbol, stock &s,
int& symbolHash, int& hashIndex, int& usedIndex)
{
symbolHash = this->hashStr( symbol ); // hash to try to reduce our search.
hashIndex = symbolHash % maxSize;
usedIndex = hashIndex;
if ( hashTable[hashIndex].symbol != NULL &&
strcmp( hashTable[hashIndex].symbol , symbol ) == 0 )
{
delete hashTable[hashIndex].symbol;
hashTable[hashIndex].symbol = NULL;
return true;
}
for ( int myInt = 0; myInt < maxSize; myInt++ )
{
++usedIndex %= maxSize;
if ( hashTable[usedIndex].symbol != NULL &&
strcmp( hashTable[usedIndex].symbol , symbol ) == 0 )
{
delete hashTable[usedIndex].symbol;
hashTable[usedIndex].symbol = NULL;
return true;
}
}
return false;
}
Noticing that i have a stock &s as a parameter, i can use it like this:
s = &hashTable[usedIndex];
delete s.symbol;
s.symbol = NULL;
hashTable[usedIndex] = &s;
This does work however, it results in a memory leaks. Even then, i am not sure if it is good object orinted design.
here is my header, where stock and all that stuff is initialized and defined.
//hash.h
private:
friend class stock;
int isAdded; // Will contain the added hash index.
// Test for empty tables.
// Can possibly make searches efficient.
stock *hashTable; // the hashtable will hold all the stocks in an array
};
// hashtable ctor
hash::hash(int capacity) : isAdded(0),
hashTable(new stock[capacity]) // allocate array with a fixed size
{
if ( capacity < 1 ) exit(-1);
maxSize = capacity;
// We can initialize our attributes for the stock
// to NULL, and test for that when searching.
for ( int index = 0; index < maxSize; index++ )
{
hashTable[index].name = NULL;
hashTable[index].sharePrice = NULL;
hashTable[index].symbol = NULL;
}
}
// stock.h
...
friend class hashmap;
private:
const static int maxSize; // holds the capacity of the hash table minus one
date priceDate; // Object for the date class. Holds its attributes.
char *symbol;
char *name;
int sharePrice;
};
My question is still just, how do i preform a safe remove?
s = &hashTable[usedIndex];
delete s.symbol;
s.symbol = NULL;
hashTable[usedIndex] = &s;
That seems to work, but results in memory leaks! How is this done safely?
delete hashTable[usedIndex].symbol;
hashTable[usedIndex].symbol = NULL; <-- without doing this.
The status of the slot in the array (empty, etc) should not be recorded in the stock instance. That's bad object oriented design. Instead, I need to store the status of an array slot in the array slot itself.
How would i do that?

NOTE: This answer is just addressing
some of the things you are doing
incorrectly. This is not the best way
to do what you are doing. An array of
stock** would make more sense.
Doesn't your stock class have a constructor? You don't need to know anything about the stock class if it is a proper object:
hash::hash(int capacity) // change this to unsigned and then you can't have capacity < 0
: isAdded(0)
, hashTable(0) // don't call new here with bad parameters
{
if ( capacity < 1 ) exit(-1); // this should throw something, maybe bad_alloc
maxSize = capacity;
hashTable = new stock[capacity]; // this calls the stock() constructor
// constructor already called. All this code is useless
// We can initialize our attributes for the stock
// to NULL, and test for that when searching.
// for ( int index = 0; index < maxSize; index++ )
// {
// hashTable[index].name = NULL;
// hashTable[index].sharePrice = NULL;
// hashTable[index].symbol = NULL;
// }
}
class stock {
char* name; // these should be std::string as it will save you many headaches
char* sharePrice; // but I'll do it your way here so you can see how to
char* symbol; // avoid memory leaks
public:
stock() : name(0), sharePrice(0), symbol(0) {}
~stock() { delete[] name; delete[] sharePrice; delete[] symbol; }
setName(const char* n) { name = new char[strlen(n)+1]; strcpy(name, n); }
setPrice(const char* p) { sharePrice = new char[strlen(p)+1]; strcpy(sharePrice, p); }
setSymbol(const char* s) { symbol = new char[strlen(s)+1]; strcpy(symbol, n); }
const char* getName() const { return name; }
const char* getPrice() const { return sharePrice; }
const char* getSymbol() const { return symbol; }
}

To get good object oriented design, a collection should be agnostic of what is stored in it. This really has nothing to do with using the delete operator per se, but requiring an object (your stock in this case) to store data structure specific code is.
There are two plans things I can see to quickly fix this issue.
Use an array of stock * instead of just stock. Then a null value will mean the slot is open, and a non-null value will mean the slot can be used. In this plan you would call new and delete on the entire stock object as it is inserted and then as it is removed, which is more object oriented than just the symbol.
Create a HashSlot class that wraps the stock item, adding the book keeping values that are needed.
Your hash table would then be an array of HashSlot items.
I prefer the second. In either case, stock should have a destructor that clears up its own internal memory.

It looks like you're using (or trying to use) open addressing with linear-probing for collision resolution. In that case, you need to somehow mark items as deleted (as opposed to empty), so that you can still access items which fall after deleted items. Otherwise, you won't be able to lookup certain items because your probing sequence will be terminated prematurely if it finds a deleted bucket. Therefore, you won't be able to access certain items in the table anymore and that's probably why you're getting a memory leak.
Basically, you're supposed to start at the hash index, compare the item with your key, and then if it isn't equal to your key, increment to the next index and repeat until either you find the item, or until you encounter an empty bucket. If you find the item, delete the item and mark that index as deleted. But the important thing is that you have some way to distinguish between an empty hash bucket, and a deleted hash bucket, otherwise a deleted bucket will cause you to terminate your probing sequence early.
As for "good object oriented design", there is no inherent property of object-oriented programming that necessarily makes using delete a bad design. Every data structure that allocates memory has to free it somehow. What you're probably referring to is the fact that it's usually safer and less work to implement classes that don't manage their own memory, but rather delegate that responsibility to pre-made container classes, like std::vector or std::string

I have developed an array based implementation of a hashTable with several stock names, symbols, prices, and the like. I need to remove a stock from my array. I am told that using the delete operator is bad object oriented design. What is the good object oriented design for deletion?
Well, one of the key principles behind object oriented design is reusability.
Hence, the only good object oriented design is to reuse the solutions that have already been developed for you!
C++ comes with a perfecetly good map class. Most recent compilers also support TR1, which adds a hash table under the name unordered_map.
The Boost libraries also contain an implementations of unordered_map in case you're stuck on a compiler without TR1 support.
As for your question about delete:
I'm not sure who told you that delete is "bad object-oriented design", or why, but what they might have meant is that it is bad C++ design.
A common guideline is that you should never explicitly call delete. Instead, it should be called implicitly through the use of the RAII idiom.
Whenever you create a resource that must, at some later point, be deleted, you wrap it in a small stack-allocated object, whose destructor calls delete for you.
This guarantees that it gets deleted when the RAII object goes out of scope, regardless of how you leave the scope. Even if an exception is thrown, the object still gets cleaned up, its destructor called, and your resource deleted. If you need more complex ways to manage the object's lifetime, you might want to use smart pointers, or just extend your RAII wrapper with copy constructor and assignment operator to allow ownership of the resource to be copied or moved.
That is good C++ practice, but has nothing to do with object-oriented design. Not everything does. OOP isn't the holy grail of programming, and not everything has to be OOP. Good design is much more important than good OOP.

Related

How to delete class as this and set it as null in c++

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.

need help for 2d array in class (c++)

In this situation, I want to delete book, but I try declare this code, its not working.
class Library {
private:
Book **books;
int counter;
public:
Library() {
books = NULL;
counter = 0;
}
void Add(INPUT &tmp) {
books = new Book*[counter];
++counter;
}
void Delete() {
--counter;
delete[] books[counter];
books[counter] = NULL;
}
int getCounter() {
return this->counter;
}
~Library() {
delete[] books;
}
};
Before you get deleting to work, you need to get adding right.
In addition to what Jeffrey said, your Add function probably doesn't work correctly due to an "out by one" error. In the first call you will have books = new Book*[0];. Allocating a zero sized array is legal (see here) but you will not be able to store anything in it.
If you can use a std::vector it will make your code much simpler and less error prone.
class Library {
private:
std::vector<Book> books;
// no need for counter, std::vector has size()
public:
// no need for a constructor, the default constructor
// will correctly construct 'books'
void Add(INPUT &tmp) {
// not sure how you convert 'INPUT' to 'Book'
books.push_back(tmp);
// this handles all of the memory management for you
}
void Delete() {
// you need to ensure that books is not empty
books.pop_back();
}
int getCounter() {
return books.size();
}
// no need for a destructor, the default one will
// do everything
};
If you need two dimensions, then the code is similar but will use a vector of vector.
Book **books;
is a pointer to a pointer to a book. It is the old style way of having a list of books (as pointers) or a list of list of books.
Library() {
books = NULL;
counter = 0;
}
This will create an empty library. No books.
void Add(INPUT &tmp) {
books = new Book*[counter];
++counter;
}
First thing to notice is that you are not using the tmp book. So you probably won't succeed in storing it anywhere, without using it.
Second thing is that books = new Book*[counter]; allocates a library of books. Space for storing some books. You probably should do that in the constructor. If you do it there, every time you try to add a book, you'll lose all the others, and you'll also leak memory.
There's two possibilities here. You have an old-timer C++ professor, and you'll need to learn about pointers and pointers to pointers, and new, delete. Or you could learn about std::vectors and smart-pointers. This would be a better idea, but I can't tell you how well it will be received in your class.
Also, please state what INPUT is defined as.

Managing objects returned from C++ function

I am wondering how one would go about returning a new object from a C++ function. For example, I have a SQLite wrapper which used to mix in Objective-C and I modifying it to be purely C++.
So, for example:
list<char*> * SqliteWrapper::RunQuery(const char *query)
{
list<char*> * result = new list<char*>();
//Process query
return result;
}
the issue that I can see in this, is that who owns the object? The calling class or the class that created the object? What is worse, is that this is very prone to memory leaks. If the caller object does not delete the newly created object, the app will end up with a memory leak.
Now that I think about this, this would make a lot of sense:
int SqliteWrapper::RunQuery(const char *query, list<char*>& result)
{
//Process query
return errorCode;
}
Are there any other approaches to this? I have been a C# programmer for a while and only now am starting to work heavily with C/C++.
Many programmers do this:
If it is a pointer that is returned, I am being given the object's identity (it's location in memory is unique) I must manage that. I am responsible for deleting it.
(Pointer = my job)
references however let you pretend you are being passed the object, to look at and use. you are not responsible for deleting these, something else is.
BUT:
"Naked pointers" may be frowned upon for code like this (it's very subjective) so some would say use a "unique_ptr" to that, these can be moved, and delete what they point to when deleted (unless the stuff is moved out of them), by returning one and not using it, it will be deleted.
(tell me if you want me to flesh this out, see also "shared_ptr" if multiple things have a pointer, this will delete what it points to when the last shared_ptr pointing to it is deleted)
Addendum 1
unique_ptr<list<char*>> SqliteWrapper::RunQuery(const char *query)
{
list<char*> * result = new list<char*>();
//Process query
return make_unique<list<char*>>(result);
}
Remember you can only move, not copy unique_ptrs
Well. You are right.
First example would be a bad style, since in such a code is hardly readable and it is hard to track bugs in it.
Usually people use the second approach with reference.
In the same way you can use pointer, allocating the return object before function call.
Third approach would be to use class instead of function. It is convinient if your function does complicated process with many parameters. In this case you store result as a data member of the class and ownership is obvious:
class SqliteWrapper {
...
class ProcessQuery {
public:
ProcessQuery():fQ(0),fP1(0){}
SetQuery(const char *query){ fQ = query; }
SetP1(int p1){ fP1 = p1; }
...
list<char*> GetResult(){ return fR; } // copy
int Run();
private:
const char *fQ;
int fP1;
...
list<char*> fR;
}
...
}
int SqliteWrapper::Process::Run()
{
//Process query
return errorCode;
}

Good Object Oriented Design When Deleting, C++

The code below deletes the symbol associated with the stock object just fine. Its just bad object oriented design.
The way that i am searching for each stock symbol is by using a != or == test for NULL.
bool hashmap::remove(char const * const symbol, stock &s,
int& symbolHash, int& hashIndex, int& usedIndex)
{
if ( isAdded == 0 ) return false;
if ( hashTable[isRemoved].symbol == symbol ) return true;
else
{
symbolHash = this->hashStr( symbol );
hashIndex = symbolHash % maxSize;
usedIndex = hashIndex;
}
for ( int integer = 0; integer < maxSize; integer++ )
{
if ( hashTable[usedIndex].symbol != NULL &&
strcmp( hashTable[usedIndex].symbol, symbol ) == 0 )
{
isAdded--;
isRemoved = hashIndex;
s = &hashTable[usedIndex];
delete hashTable[usedIndex].symbol;
hashTable[usedIndex].symbol = NULL;
return true;
}
++usedIndex %= maxSize; // wrap around if needed
}
return false;
}
Im wondering now, if i delete in a such a way that:
hashTable[usedIndex].symbol = hashTable[NULL].symbol
Thereby, changing the way I logically test for an empty or found stock symbol. Is their a way to remove my stock symbol without having to redo the aspect of finding and searching?
Is this the correct way to remove in object oriented design?
First of all, "object oriented design" is very ambiguous.
Is isAdded a member variable? It isn't clear that it is and creates another dependency on this function that isn't obvious when looking at the signature. Same thing goes for isRemoved.
Generally, a function that takes 5 arguments is getting close to showing that there is too much dependencies on this function (nevermind the invisible dependencies in isAdded, isRemoved, and hashTable).
I'm not sure what type hashTable is, but you should never have to call delete in 2009. You can use auto_ptr, shared_ptr, unique_ptr (in C++0x). These will take care of freeing your resource when it is not needed anymore. If you are using an STL container, then don't use auto_ptr though.
If you would like to use a hashtable in C++, you really should consider using a hash_map. That will be a much better implementation than 99.9999% of us can accomplish.
When using a hash_map, you can call void erase(iterator first, iterator last) to erase/delete an element.
How is an insert collision handled? Most standard solutions—such as a linear search for an open slot, or generating a new hash—make deleting an element problematic. If deletions are common, consider using a list structure instead.

std::map inizialitazion (only one time)

I have a function that translates data using std::map
struct HistoParameter
{
int nbins;
float first;
float last;
HistoParameter(int _nbins, int _first, int _last) :
nbins(_nbins), first(_first), last(_last) {};
};
HistoParameter* variable_to_parameter(char* var_name)
{
std::map<const std::string, HistoParameter*> hp;
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
// ...
return hp[var_name];
}
My struct is very light, but image it can be heavy. The prolem is that every time I call this function it create a lot of HistoParameter objects, maybe a switch case is more efficient. First question: I'm creating garbage?
Second solution:
bool first_time = true;
HistoParameter* variable_to_parameter(char* var_name)
{
static std::map<const std::string, HistoParameter*> hp;
if (first_time)
{
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
// ...
}
first_time = false;
return hp[var_name];
is it ok? Better solution?
The second solution seems OK to me - you can say:
if ( hp.empty() ) {
// populate map
}
I would also consider making it a map of values rather than pointers - I don't see you need dynamic allocation here:
std::map <std::string, HistoParameter> hp;
then:
hp["ph_pt"] = HistoParameter(100,0,22000);
Note you don't need the explicit std::string conversion. Or better still:
hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000 )));
The first solution produces a lot of garbage. Why don't you return the class by value? It's quite lightweight, and you wouln't have to dynamically allocate it.
HistoParameter variable_to_parameter(char* var_name)
{
static std::map<const std::string, HistoParameter> hp;
if ( hp.empty() )
{
hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000) ) );
hp.insert( std::make_pair( "ph_eta", HistoParameter(100,-3,3) ) );
//...
}
return hp[var_name];
}
If the class returned gets larger, and you want a power-tool, then try out boost::flyweight.
If you don't want to pass back a big structure, you can do:
HistoParameter& variable_to_parameter(char* var_name)
{
// same code
}
... and even throw in a const if you want it immutable.
Edit: added make_pair, as suggested by Niel.
Your second solution should certainly improve efficiency, but isn't (at least IMO) the best implementation possible. First of all, it makes first_time publicly visible, even though only variable_to_parameter actually cares about it. You've already made hp a static variable in the function, and first_time should be as well.
Second, I would not use pointers and/or dynamic allocation for the HistoParameter values. At one int and two floats, there's simply no reason to do so. If you're really passing them around so much that copying became a problem, you'd probably be better off using some sort of smart pointer class instead of a raw pointer -- the latter is more difficult to use and much more difficult to make exception safe.
Third, I'd consider whether it's worthwhile to make variable_to_parameter into a functor instead of a function. In this case, you'd initialize the map in the ctor, so you wouldn't have to check whether it was initialized every time operator() was invoked. You can also combine the two, by have a static map in the functor. The ctor initializes it if it doesn't exist, and operator() just does a lookup.
Finally, I'd note that map::operator[] is primarily useful for inserting items -- it creates an item with the specified key if it doesn't exist, but when you're looking for an item, you usually don't want to create an item. For this, you're generally better off using map.find() instead.
I'd have a std::map< std::string, HistoParameter *> member and do
InitializeHistoParameter()
{
myMap["ph_pt"] = new ...
myMap["ph_eta"] = new ...
}
And then
HistoParameter* variable_to_parameter(char* var_name)
{
return myMap[var_name];
}
either way, you are creating memory leak.
each time the = operator is called, for example:
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
you are creating a new HistoParameter object and pairing the key "ph" with this most recent object, leaving the previous one dangling.
If creating a new object each time is your actual intent, you probably need to call
delete hp[std::string("ph_pt")];
before the new operation.
My suggestion is to avoid raw new operations as much as possible and resort to smart pointers such as boost::share_ptr for object life time management.