gpt4 book ai didi

c++ - Linux 中的段错误,在 Mac OS 上工作正常

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:27:17 25 4
gpt4 key购买 nike

我正在做一个 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;
}

字符串设置.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 { };

最佳答案

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(除非您实际上要删除该节点)。

关于c++ - Linux 中的段错误,在 Mac OS 上工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32835448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com