我正在进行C ++家庭作业,我们必须在其中构建单链表的哈希表。我已经在Mac上编写了我的代码 - 它可以很好地编译并完美地生成预期的输出。但是,当我在Linux中运行程序时,我得到了段错(核心转储)。使用gdb进行调试时,我收到消息
Program received signal SIGSEGV, Segmentation fault.
__strcmp_sse2 () at ../sysdeps/x86_64/multiarch/../strcmp.S:210
210 ../sysdeps/x86_64/multiarch/../strcmp.S: No such file or directory.
我在本网站上的其他帖子中读到,在这种情况下gdb会产生误导,而且问题与“strcmp”功能无关。但是,我无法查看代码中的问题所在。如果有人能指出我正确的方向,那将非常感激。 TIA。
//string_set.cpp
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "string_set.h"
using namespace std;
string_set::string_set() {
for (int i = 0; i < HASH_TABLE_SIZE; i++) { //initializing empty hash table
hash_table[i] = NULL;
} //end for
iterator_index = 0;
iterator_node = hash_table[iterator_index];
}
void string_set::add(const char *s) {
int hash_val = hash_function(s);
if (contains(s) == 1) {
throw duplicate_exception();
} //end if
node *a = new node;
if (a==NULL) {
throw memory_exception();
} //end if
a->s = new char[strlen(s) + 1];
if (a == NULL) {
delete a;
throw memory_exception();
} //end if
strcpy(a->s, s);
a->next = hash_table[hash_val];
hash_table[hash_val] = a;
if (contains(s) == 0) {
throw memory_exception();
} //end if
else {
reset();
} //end else
}
void string_set::remove(const char *s) {
if (contains(s) == 0) {
throw not_found_exception();
} //end if
int hash_val = hash_function(s);
node *prev = new node;
prev = hash_table[hash_val];
node *ptr = new node;
ptr = hash_table[hash_val];
while (strcmp(ptr->s, s) != 0) { //
prev = ptr;
ptr = ptr->next;
} //end while
if (prev == ptr) { //if node to be deleted is first in list
hash_table[hash_val] = ptr->next;
} //end if
delete ptr->s;
prev->next = ptr->next;
delete ptr;
reset();
}
int string_set::contains(const char *s) {
int hash_val = hash_function(s);
node *ptr = new node;
ptr = hash_table[hash_val];
while (ptr != NULL) {
if (strcmp(s, ptr->s) == 0) { //
delete ptr;
return 1;
} //end if
else {
ptr = ptr->next;
} //end else
} //end while
return 0;
}
void string_set::reset() {
iterator_index = 0;
iterator_node = hash_table[iterator_index];
}
const char *string_set::next() {
if (iterator_node != NULL) {
char copy[strlen(iterator_node->s) + 1];
strcpy(copy, iterator_node->s);
iterator_node = iterator_node->next;
return copy;
} //end if
while (iterator_index < HASH_TABLE_SIZE - 1) {
while (iterator_node == NULL) {
++iterator_index;
iterator_node = hash_table[iterator_index];
if ((iterator_index == HASH_TABLE_SIZE - 1) && (iterator_node == NULL)) {
return NULL;
}
} //end nested while
char copy[strlen(iterator_node->s) + 1];
strcpy(copy, iterator_node->s);
iterator_node = iterator_node->next;
return copy;
} //end while
return NULL;
}
string_set::~string_set() {
reset();
node *ptr = new node;
ptr = iterator_node;
while (ptr != NULL) {
delete ptr->s;
next();
ptr = iterator_node;
} //end while
delete ptr;
}
int string_set::hash_function(const char *s) {
int sum = 0;
for (unsigned int ind = 0; ind < strlen(s); ind++) { //summing elements in string s
sum += s[ind];
sum = sum % HASH_TABLE_SIZE;
} //end for
return sum % HASH_TABLE_SIZE;
}
string_set.h
using namespace std;
class string_set {
public:
/*Purpose
initialize the set to contain no elements
* Preconditions
none
* Exceptions
none
*/
string_set();
/*Purpose
* add s to the set
* if s is successfully added, reset the iterator
* Preconditions
* s is a legal string
* Exceptions
* if s is already present then throw duplicate_exception
* else if s there is not enough memory to add s then throw memory_exception
*/
void add(const char *s);
/*Purpose
* remove s from the set
* if s is successfully removed, reset the iterator
* Preconditions
* s is a legal string
* Exceptions
* if s is not present then throw not_found_exception
*/
void remove(const char *s);
/*Purpose
* return 1 if s is in the set and 0 otherwise
* Preconditions
* s is a legal string
* Exceptions
* none
*/
int contains(const char *s);
/*Purpose
* reset the iterator to the first element
* Preconditions
* none
* Exceptions
* none
*/
void reset();
/*Purpose
* return a pointer to the next set element
* return NULL if no more elements remain
* Preconditions
* none
* Exceptions
* none
*/
const char *next();
/*Purpose
* delete all dynamically allocated memory
* Preconditions
* none
* Exceptions
* none
*/
~string_set();
private:
/*Purpose
* return the hash value h associated with s
* h must consist of: (sum of the characters in s) mod HASH_TABLE_SIZE
* Preconditions
* s is a legal string
* Exceptions
* none
* Examples
* hash_function("a") returns 97
* hash_function("ab") returns 95
* hash_function("ba") returns 95
* hash_function("") returns 0
*/
int hash_function(const char *s);
enum {HASH_TABLE_SIZE = 100};
class node {
public:
char *s;
node *next;
};
// hash_table[i] is the head of a linked list of nodes
node *hash_table[HASH_TABLE_SIZE];
// iterator position
int iterator_index; // index in hash_table
node *iterator_node; // node in hash_table[iterator_index];
};
class duplicate_exception { };
class memory_exception { };
class not_found_exception { };
答案 0 :(得分:0)
contains
函数中的以下代码行:
if (strcmp(s, ptr->s) == 0) { //
delete ptr;
将删除刚找到的节点的内存,当您稍后尝试使用该节点时,会导致未定义的行为。
在代码的几个地方,你为一个指针分配一个新节点,然后立即将指针指向另一个位置 - 这将导致内存泄漏,并可能导致你删除你不想要的东西。
node *ptr = new node;
ptr = hash_table[hash_val];
应该是
node *ptr = hash_table[hash_val];
然后不需要相应的delete
(除非您实际上是删除了节点)。