嘿伙计们已经完成了我的代码,当我尝试运行时,我收到了“abort trap 6”错误。我不知道这个错误是什么,以及如何找出我的代码破坏的地方。对c来说比较新,所以谢谢你和我一起玩。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define HASH_MULTIPLIER 65599
int htsize;
struct NodeType {
char *str;
int count;
struct NodeType *next;
};
typedef struct NodeType Node;
/*Function prototypes*/
char *lowercase(char *str);
Node **ht_create(void);
unsigned int hash(const char *str);
int ht_insert(Node **Table, char *word);
void ht_print(Node **Table);
void ht_destroy(Node **Table);
int main(int argc, char *argv[])
{
int n = 0; // current number of strings
char *line = NULL; // line buffer argument to getline()
size_t length = 0; // buffer size argument to getline()
char *token; // token returned by strtok()
char *delim = " .,;:!\"?\n"; // delimiter characters for strtok()
char *word;
Node** Table;
if (argc <= 1) {
printf("ERROR: Usage: %s table_size\n", argv[0]);
return 1;
}
htsize = atoi(argv[1]);
Table = ht_create();
while (1) {
if (getline(&line, &length, stdin) == -1) // read next line
break; // exit loop when no more lines
token = strtok(line, delim); // extract next token from line
while (token != NULL) {
word = lowercase(token); // store in word a copy of the token in lower-case
ht_insert(Table, word); // insert word into table
token = strtok(NULL, delim); // extract next token
}n++;
}
ht_print(Table);
ht_destroy(Table);
return 0;
}
/* returns an integer for place in Table*/
unsigned int hash(const char *string)
{
int i;
unsigned int h = 0U;
for (i = 0; string[i] != '\0'; i++)
h = h * HASH_MULTIPLIER + (unsigned char) string[i];
return h % htsize;
}
/* creates a heap-allocated hash table with htsize buckets */
Node **ht_create(void)
{
Node** Table;
Table = (Node**)malloc(sizeof(Node*)); //allocates memory for size of Table
Table[0] = (Node*)malloc(sizeof(Node)); //allocates memory for bucket
if (Table == NULL)
{
fprintf(stderr, "malloc failed.\n"); //exits program if Table is empty
exit(0);
}
int i = 0; //initialize int i
for (i = 0; i <= htsize; i++){ //for loop to create htsize buckets
Table[i] = (Node*)malloc(sizeof(Node)); //allocates memory for each bucket
Table[i] -> count = 0; //initilizes count
Table[i] -> str = " "; //initializes str to empty string
Table[i] -> next = NULL; //initializes next
}
return Table; //returns hash table
}
/* inserts word into heap allocated hash table*/
int ht_insert(Node **Table, char *word)
{
int index = hash(word); //runs hash function to create index for entry
Node* entry = Table[index]; //creates nodetype "entry" = the index of the table
//previosuly set
Node* temp = entry; //sets temp nodetype = to entry
if (entry == NULL) //if the index is empty run body
{
Node* newEntry = (Node*)malloc(sizeof(Node)); //allocates memory for the new entry for testing
if (newEntry == NULL) //if new entry is empty jump to error
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
newEntry -> next = NULL; //if passed, set next to NULL
newEntry -> str = word; //make str = word
if (newEntry -> str == NULL) //if the word is empty print error
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
//strcpy(newEntry -> str, word); //if passed, copy word
newEntry -> count = 1; //set count to 1 to make sure the word entered is atleast 1
Table[index] = newEntry; //the bucket at i = to new entry
return 1;
}
while (entry != NULL) //if word is already inside of a the table run body
{
//if ((entry -> str = strdup(word)) == 0)
if (strcmp(entry -> str, word) == 0) //if word is same as word at current i bucket
{
entry -> count++; //add count by 1
return 1;
}
temp = entry; //set temp = entry
entry = entry -> next; //go to next entry in linked list
}
Node* newEntry = (Node*)malloc(sizeof(Node)); //allocates memory for new entry
if (newEntry == NULL) // if new entry is empty jump to error
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
newEntry -> next = NULL; //set next for new entry = null
newEntry -> str = word; //set new entry str = word
if (newEntry -> str == NULL) //if new entry str is null jump to error
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
newEntry -> str = strdup(word); //
strncpy(newEntry -> str, word, strlen(word) - 1);
newEntry -> count = 1;
temp -> next = newEntry;
return 1;
}
/* prints heap allocated hash table */
void ht_print(Node **Table)
{
int i = 0; //initialize i = 0
Node* entry; //nodetype entry
for (i = 0; i < htsize; i++) //for loop to run through each bucket
{
entry = Table[i]; //entry = ith bucket
printf("HT[%d]: ", i); //print ith bucket name
while (entry != NULL) //while there is information in a bucket
{
if (entry -> count != 0 && strcmp(entry -> str, " ") > 0) //if there is an entry and its not an empty string
printf(" [%s , %d]", entry -> str, entry -> count); //print str and count
entry = entry -> next; //move on to next bucket
}
printf("\n");
}
}
/* destroys heap allocated hash table */
void ht_destroy(Node **Table)
{
int i = 0; //initialize i = 0
Node* entry; //nodetype entry
Node* temp; //nodetype temp
for (i = 0; i < htsize; i++) //for loop to run through each bucket
{
entry = Table[i]; //entry = ith bucket
temp = entry; //temp = entry = ith bucket
while (entry != NULL) //while entry is not empty: body statement
{
if (strcmp(entry -> str, " ") > 0) //if str is not an empty string
{
temp = entry -> next; //temp = next bucket
free(entry -> str); //free memory for str in entry
free(entry); //free up memory for entry
entry = temp; //entry is temp (next bucket)
}
}
}
free(*Table); //Free table
free(Table); //free table
}
/*Convert string str to lower-case */
char *lowercase(char *str)
{
char *word, *ptr;
if ( (word = strdup(str)) != NULL) {
for (ptr = word; *ptr != '\0'; ptr++)
*ptr = tolower(*ptr);
}
return word;
}
该代码旨在专门接收一个文本文件:
Little Boy Blue,
Come blow your horn,
The sheep's in the meadow,
The cow's in the corn;
Where is that boy
Who looks after the sheep?
Under the haystack
Fast asleep.
Will you wake him?
Oh no, not I,
For if I do
He will surely cry.
输出
HT[0]: [i? , -264221488] [under , 1] [oh , 1] [surely , 1]
HT[1]: [i? , -264221360] [that , 1]
HT[2]: [i? , -264221232] [horn , 1] [meadow , 1] [is , 1] [fast , 1] [asleep , 1]
HT[3]: [i? , -264221104] [cow's , 1] [corn , 1] [who , 1] [him , 1] [for , 1] [if , 1] [do , 1]
HT[4]: [i? , -264220976] [sheep's , 1] [where , 1] [no , 1] [not , 1]
HT[5]: [wake , 1] [cry , 1]
HT[6]:
HT[7]:
HT[8]: [under , 1] [oh , 1] [surely , 1]
HT[9]: [blue , 1] [blow , 1] [looks , 1]
HT[10]:
HT[11]: [your , 1] [in , 2]
HT[12]: [that , 1]
HT[13]: [little , 1] [haystack , 1] [i , 2]
HT[14]: [will , 2]
HT[15]:
HT[16]: [horn , 1] [meadow , 1] [is , 1] [fast , 1] [asleep , 1]
HT[17]: [sheep , 1]
HT[18]: [you , 1]
HT[19]: [come , 1] [the , 6]
HT[20]: [cow's , 1] [corn , 1] [who , 1] [him , 1] [for , 1] [if , 1] [do , 1]
HT[21]: [after , 1]
HT[22]: [boy , 2] [he , 1]
正确输出
HT[0]: [under, 1] [oh, 1]
HT[1]: [that, 1]
HT[2]: [meadow, 1]
HT[3]: [cow's, 1] [for, 1] [if, 1]
HT[4]: [sheep's, 1] [where, 1] [no, 1] [not, 1]
HT[5]: [wake, 1] [cry, 1]
HT[6]:
HT[7]:
HT[8]: [surely, 1]
HT[9]: [blue, 1] [blow, 1] [looks, 1]
HT[10]:
HT[11]: [your, 1] [in, 2]
HT[12]:
HT[13]: [little, 1] [haystack, 1] [i, 2]
HT[14]: [will, 2]
HT[15]:
HT[16]: [horn, 1] [is, 1] [fast, 1] [asleep, 1]
HT[17]: [sheep, 1]
HT[18]: [you, 1]
HT[19]: [come, 1] [the, 6]
HT[20]: [corn, 1] [who, 1] [him, 1] [do, 1]
HT[21]: [after, 1]
HT[22]: [boy, 2] [he, 1]
我在使用xcode和gdb的mac上,我不知道如何检查这是在哪里破坏。任何帮助将不胜感激。
感谢
答案 0 :(得分:1)
EDIT1:在ht_create()函数中完成,将Table数组元素初始化为NULL,这在初始帖子中遗漏了。
EDIT2:完成更新已修改的ht_print()和ht_destroy()函数。
Node **ht_create(void)
{
Node** Table;
// Allocating array (of size htsize) of Node pointers
Table = (Node**)malloc(htsize * sizeof(Node*)); <-- NOTE: Change done here, used htsize for allocation
//Table[0] = (Node*)malloc(sizeof(Node)); <-- NOTE: Commented this line, stray code, Table[0] will be allocated in for() loop
if (Table == NULL)
{
fprintf(stderr, "malloc failed.\n"); //exits program if Table is empty
exit(0);
}
// NOTE: Code added for Table[i] NULL initialization
int i = 0;
for (i = 0; i < htsize; i++){
Table[i] = NULL;
}
return Table;
}
int ht_insert(Node **Table, char *word)
{
int index = hash(word);
Node* entry = Table[index];
Node *temp;
if (entry == NULL)
{
// First entry at Table[index]
Node* newEntry = (Node*)malloc(sizeof(Node));
if (newEntry == NULL)
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
newEntry->word = strdup(word); <-- NOTE: Change here to use strdup()
if (newEntry->word == NULL)
{
fprintf(stderr, "strdup() failed at insert\n");
free(newEntry);
return 0;
}
newEntry->count = 1;
newEntry->next = NULL;
Table[index] = newEntry;
return 1;
}
// Go to the end of list at Table[index]
// Also check if input word is same as one existing entry in the list at Table[index], if yes, increase repeat count for the word
while (NULL != entry)
{
// Check if input word is same as word stored in current node
if (0 == strcmp(word, entry->word))
{
entry->count++;
return 1;
}
temp = entry;
entry = entry->next;
}
// New entry in the list at Table[index]
Node* newEntry = (Node*)malloc(sizeof(Node));
if (newEntry == NULL)
{
fprintf(stderr, "malloc failed at insert\n");
return 0;
}
newEntry->word = strdup(word);
if (newEntry->word == NULL)
{
fprintf(stderr, "strdup() failed at insert\n");
free(newEntry);
return 0;
}
newEntry->count = 1;
newEntry->next = NULL;
temp->next = newEntry;
return 1;
}
/* prints heap allocated hash table */
void ht_print(Node **Table)
{
int i = 0; //initialize i = 0
Node* entry; //nodetype entry
for (i = 0; i < htsize; i++) //for loop to run through each bucket
{
entry = Table[i]; //entry = ith bucket
printf("HT[%d]: ", i); //print ith bucket name
while (entry != NULL) //while there is information in a bucket
{
if (entry->word != NULL) //if there is an entry and its not an empty string
printf(" [%s , %d]", entry->word, entry -> count); //print str and count
entry = entry -> next; //move on to next bucket
}
printf("\n");
}
}
/* destroys heap allocated hash table */
void ht_destroy(Node **Table)
{
int i = 0; //initialize i = 0
Node* entry; //nodetype entry
Node* temp; //nodetype temp
for (i = 0; i < htsize; i++) //for loop to run through each bucket
{
entry = Table[i]; //entry = ith bucket
temp = entry; //temp = entry = ith bucket
while (entry != NULL) //while entry is not empty: body statement
{
temp = entry -> next; //temp = next bucket
if (entry -> word != NULL) //if str is not an empty string
{
free(entry -> word); //free memory for str in entry
}
free(entry); //free up memory for entry
entry = temp; //entry is temp (next bucket)
}
}
free(Table); //free table
}