2014-03-01 51 views
0
#include<iostream> 
#include<vector> 
#include "hashtable.h" 

using namespace std; 

class dummy 
{ 
public: 
int a; 
vector<int> k; 
dummy() 
{ 
    a= 10; 
    k.push_back(10); 
    k.push_back(20); 
} 

~dummy() 
{ 
    cout<<"clearing dummy"<<endl; 
    k.clear(); 
    cout<<"comple"<<endl; 
} 
}; 


class parent 
{ 
public: 
dummy *p; 
Hashtable *nodes_hashtable; 
parent() 
{ 
    p = new dummy(); 
} 

void create_nodes_hashtable(); 

virtual ~parent() 
{ 
    cout<<"clearing parent"<<endl; 
    delete(p); 
    delete(nodes_hashtable); 
} 

}; 


//given the hashtable,updates the values in the hashtable 
void parent :: create_nodes_hashtable() 
{ 
nodes_hashtable = new(std::nothrow) Hashtable(500); 

//check :if the hashtable has been created 
if(NULL == nodes_hashtable) 
{ 
    cout<<"out of memory"<<endl; 
} 

for(unsigned int i = 0;i<20 ;i++) 
{  
    //normalising the key ,so that the key lies within the range of the hashtable 
    int key = i;//get_nodes_hashtablekey(i,i); 
    (*nodes_hashtable).add_element(key,i,i); 
} 
} 


class child: public parent 
{ 
public: 
    child() 
    { 
} 
~child() 
{ 
    cout<<"clearing child"<<endl; 
} 
}; 

int main() 
{ 
child c; 
cout<<"gng of scope"<<endl; 
return(0); 
} 

的Hashtable.h代码如下:段故障与继承

#ifndef _HASHTABLE_H_ 
#define _HASHTABLE_H_ 

#include<vector> 
#include<iostream> 
#include<string> 
#include<algorithm> 
//returns this value if the object corresponding to the key is not found in the hashtable 
#define NOT_FOUND_IN_HASHTABLE -1 

//default hashtable size 
//wen the size is not passed in the arguments 
    #define DEFAULT_HASHTABLE_SIZE 200//WINDOW_LENGTH 

    //defines the data structure hashtable 
    //the hashtable assumes that each object_identifier refers to an unique object 

    class Hashtable 
    { 

private : 

//counts the number of elements added into the hashtable 
unsigned int count_elements_added; 

//counts the number of elements removed from the hashtable 
unsigned int count_elements_removed; 

//counts the number of elements present in the hashtable 
unsigned int count_elements_present; 

//sets the size of the hashtable 
unsigned int hashtable_size; 

//the data structure (vector) that contains the objects 
//the position on the hastable is defined by 2 keys 
//one the position in the array of the hashtable : the start of the node is used 
//the second is the first element in the pair present in the hash table //end of the node is used 
std :: vector< std :: vector<std :: pair<int,int> > > hashtable; 

//intialize the hashtable 
void intialize_hashtable(); 

//checks whether the hashtable is corrupted or not 
//returns true,if the hashtable is corrupted 
//else returns false 
bool is_corrupt(); 

public : 

Hashtable() 
{ 
    hashtable_size = DEFAULT_HASHTABLE_SIZE; 
    hashtable.clear(); 
    intialize_hashtable(); 

    //counts the number of elements added into the hashtable 
    count_elements_added = 0; 

    //counts the number of elements removed from the hashtable 
    count_elements_removed = 0; 

    //counts the number of elements present in the hashtable 
    count_elements_present = 0; 
}; 

Hashtable(int hash_table_size) 
{ 
    hashtable.clear(); 
    hashtable_size = hash_table_size; 
    intialize_hashtable(); 

    //counts the number of elements added into the hashtable 
    count_elements_added = 0; 

    //counts the number of elements removed from the hashtable 
    count_elements_removed = 0; 

    //counts the number of elements present in the hashtable 
    count_elements_present = 0; 
}; 

//add elemnet to the hashtable 
void add_element(int key,int object_identifier,int object_info); 

//given the key and the object identifier 
//returns the object info 
int get_element(int key,int object_identifier); 

//delete the element from the hashtable 
void remove_element(int key,int object_identifier); 

//prints the contents of the hashtable 
void print(); 

void clear_memory() 
{ 
    std::cout<<"clearing hashtable"<<std::endl; 
    hashtable.clear(); 
    hashtable_size = 0; 
} 

~Hashtable() 
{ 
    hashtable_size = 0; 
    hashtable.clear(); 

    //counts the number of elements added into the hashtable 
    count_elements_added = 0; 

    //counts the number of elements removed from the hashtable 
    count_elements_removed = 0; 

    //counts the number of elements present in the hashtable 
    count_elements_present = 0; 

}; 
}; 

//initialize the hashtable 
inline void Hashtable :: intialize_hashtable() 
{ 
for(unsigned int i = 0;i < hashtable_size;i++) 
{ 
    std :: vector<std :: pair<int,int> > temp; 
    temp.clear(); 
    hashtable.push_back(temp); 
} 
} 

//add elemnet to the hashtable 
inline void Hashtable :: add_element(int key,int object_identifier,int object_info) 
{ 
hashtable[key].push_back(std :: pair<int,int> (object_identifier,object_info)); 

count_elements_added++; 
count_elements_present++; 

} 

//given the key and the object identifier 
//returns the object info 
//if the object has not been found then returns the macro : value 
inline int Hashtable :: get_element(int key,int object_identifier) 
{ 
//get elements from the hastable that have the same key 
std :: vector<std :: pair<int,int> > same_key_elements = hashtable[key]; 

//if the hastable array is empty then return not found 
if(same_key_elements.empty()) 
{ 
    return(NOT_FOUND_IN_HASHTABLE); 
} 

//scan thru all the elemenets in the hashtable to find if the element is present 
for(std :: vector<std :: pair<int,int> > :: iterator same_key_elements_iter = same_key_elements.begin();same_key_elements_iter != same_key_elements.end();same_key_elements_iter++) 
{ 
    //check if the object identifier is present in the array 
    if((*same_key_elements_iter).first == object_identifier) 
    { 
     //returns the object info corresponding to the object identifier  
     return((*same_key_elements_iter).second); 
    } 
} 

same_key_elements.clear(); 


//if the element has not been found then return the default value 
return(NOT_FOUND_IN_HASHTABLE); 
} 

//given an key and the element object_identifier,removes the element from the hashtable 
inline void Hashtable :: remove_element(int key,int object_identifier) 
{ 
//get elements from the hastable that have the same key 
std :: vector<std :: pair<int,int> > same_key_elements = hashtable[key]; 

//saves the remanining elements in the array after the element woth the same key has been found 
std :: vector<std :: pair<int,int> > remaining_key_elements; 
remaining_key_elements.clear(); 

//if the hastable array is empty then no deletion can take place 
if(same_key_elements.empty()) 
{ 
    return; 
} 

//scan thru all the elemenets in the hashtable to find if the element is present 
for(std :: vector<std :: pair<int,int> > :: iterator same_key_elements_iter = same_key_elements.begin();same_key_elements_iter != same_key_elements.end();same_key_elements_iter++) 
{ 
    //check if the object identifier is not present in the array 
    if(!((*same_key_elements_iter).first == object_identifier)) 
    { 
     remaining_key_elements.push_back(std :: pair<int,int> ((*same_key_elements_iter).first ,(*same_key_elements_iter).second)); 
    } 
} 

hashtable[key] = remaining_key_elements; 
same_key_elements.clear(); 
remaining_key_elements.clear(); 

//update the hashtable counts 
count_elements_removed++; 
count_elements_present--; 

} 

//checks whether the hashtable is corrupted or not 
//returns true,if the hashtable is corrupted 
//else returns false 
inline bool Hashtable :: is_corrupt() 
{ 
//the size of the hashtable should be equal to the size it was initialised 
if(hashtable.size() != hashtable_size) 
{ 
    return(true); 
} 
//the number of elements added - no. of elements removed should be equal to the no. of elements present in the hashtable 
else if((count_elements_added -count_elements_removed) != count_elements_present) 
{ 
    return(true); 
} 
//default case : 
else 
{ 
    return(false); 
} 
} 

//prints the contents of the hashtable 
inline void Hashtable :: print() 
{ 
//checks the case where the hashtable may be empty 
if(hashtable.empty()) 
{ 
    std :: cout<<"the hash table is empty"<<std :: endl; 
} 

    //printing the contents of the hashtable 
    unsigned int pos = 0; 
for(std :: vector< std :: vector<std :: pair<int,int> > > :: iterator hashtable_iter = hashtable.begin();hashtable_iter != hashtable.end();hashtable_iter++,pos++) 
{ 
    std :: cout<<"key = "<<pos; 
    std :: vector<std ::pair<int,int> > tmp = *hashtable_iter; 
    //Tools :: print(tmp); 
    std :: cout<<std :: endl; 
} 
} 

#endif 

段故障即将来临。代码的输出是:

gng of scope 
clearing child 
clearing parent 
clearing dummy 
comple 
Segmentation fault (core dumped) 

请指导如何调试此问题。我试过gdb,但我不明白分段故障的原因。

+1

你需要遵循[**三规则](http:// en。 wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29)。 – juanchopanza

+1

你应该初始化所有的指针,因此您可以sfely调用'他们delete'。或者使它们指向一个动态分配的对象,或者将它们设置为'nullptr',(或'0'或'NULL'如果预C++ 11) – juanchopanza

+0

感谢@juanchopanza – priyanka

回答

1
nodes_hashtable is point to null which would cause core dump to free null memory。 


class parent 
{ 
public: 
dummy *p; 
Hashtable *nodes_hashtable; 
parent() 
{ 
    p = new dummy(); 
nodes_hashtable=NULL; 
} 

void create_nodes_hashtable(); 

virtual ~parent() 
{ 
    cout<<"clearing parent"<<endl; 
    delete(p); 
    if(nodes_hashtable != NULL) 
     delete(nodes_hashtable); 
} 

}; 

//given the hashtable,updates the values in the hashtable 
void parent :: create_nodes_hashtable() 
{ 
if(nodes_hashtable == NULL) 
    nodes_hashtable = new(std::nothrow) Hashtable(500); 
else 
    return; 

//check :if the hashtable has been created 
if(NULL == nodes_hashtable) 
{ 
    cout<<"out of memory"<<endl; 
} 

for(unsigned int i = 0;i<20 ;i++) 
{  
    //normalising the key ,so that the key lies within the range of the hashtable 
    int key = i;//get_nodes_hashtablekey(i,i); 
    (*nodes_hashtable).add_element(key,i,i); 
} 
} 
+0

的代码仍然严重,虽然打破。这只是解决了一个特定的问题。如果一个“父母”获得了构建或分配的副本,它将会炸毁。 – juanchopanza

+0

如果代码正常工作,代码不会被破坏。也就是说,三条规则是防止你在脚下射击的一个非常好的主意。 – immibis

+0

浅拷贝问题可以通过复制构造函数和操作员=,或智能pointer.or的倍率解决定义类独居 – gabios

2

Parentdelete(nodes_hashtable);,我想你是不是为nodes_hashtable分配内存。

请使用

parent() 
{ 
    nodes_hashtable=NULL; 
    p = new dummy(); 
} 
virtual ~parent() 
{ 
    cout<<"clearing parent"<<endl; 
    delete(p); 
    if(nodes_hashtable) 
     delete(nodes_hashtable); 
} 

此代码将不会调用删除nodes_hashtable如果记忆没有被分配到它。

+0

我认为'create_nodes_hashtable'是诺伊称为 –

+0

雅那不叫,在代码块只创建子对象,并没有其他的操作与实现。 – rajenpandit

+0

+1快速回答。 –

2

nodes_hashtable是未初始化的,所以这个指针可以包含任何数据。你必须初始化它在parent构造:

parent() : 
    p(new dummy()), 
    nodes_hashtable(NULL) 
{} 

有进一步的代码可预见的条件。 你也可以删除NULL指针与大多数编译器W/O在NULL上检查它,所以没有重大的理由改变parent析构函数