C 和调试中的 Abort Trap 6 错误

Posted

技术标签:

【中文标题】C 和调试中的 Abort Trap 6 错误【英文标题】:Abort Trap 6 error in C and debugging 【发布时间】:2015-11-11 03:51:58 【问题描述】:

大家好,我的代码已经完成,当我尝试运行时,我收到“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 上,但我不确定如何检查它在哪里中断。任何帮助将不胜感激。

谢谢

【问题讨论】:

在调试器中运行你的程序。它会在这里显示一个错误:newEntry -&gt; word = word; strncpy(newEntry -&gt; word, word, strlen(word) - 1);,你想在那里做什么? strncpy 的 dest 和 src 参数似乎是相同的指针值。这是特别禁止的。 strncpy 手册页说:“字符串不能重叠”。真的不清楚你想在那里实现什么。 0) Table = ht_create(); 需要htsize = atoi(argv[1]);之后 @kaylum 感谢您的回复,我试图将有问题的字符串复制到我的节点结构的单词部分,也许我错了,但现在读回来似乎我尝试了两次?函数insert试图将当前字符串插入哈希表“Table” 1) free(entry -&gt; word); 在字面量无法释放的情况下。 (Table[i] -&gt; word = " ";) 您不能只使用赋值运算符复制字符串,因为您的main 对每个输入行使用相同的line 缓冲区。如果您使用分配,那么所有节点都将指向相同的缓冲区空间。您可能希望在Node 结构中静态分配一个固定大小的数组,然后使用strncpy 或使用strdup 分配动态内存。另外,请注意 BLUEPIXY 的评论。您在解析 htsize 之前调用了 ht_create,但前者需要后者。 【参考方案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

【讨论】:

嘿伙计,感谢您的帮助已输入您发送的内容并收到分段错误 11 错误。我对上面的代码进行了一些更改,最后得到了一个不知道出了什么问题的输出。 我之前没有编译和测试代码。发现在 ht_create() 中遗漏了 Table[i] NULL 初始化。为此编辑了帖子。希望这对您有所帮助。 ht_destroy() 有 free(*Table) 错误,更新后的帖子修改了 ht_destroy() 和 ht_print() 函数。 我的帖子仍在结构节点中使用“word”成员(根据您最初发布的原始代码)。您现在已将其修改为“str”名称。因此,您可能需要搜索和替换它。谢谢。 非常感谢,我真的被卡住了,它现在可以正常工作了!

以上是关于C 和调试中的 Abort Trap 6 错误的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 自动升级到8.21后坑-Abort trap: 6

ARM Data Abort 错误异常调试

调试错误 -Abort() 已被调用

Xcode8 pod install 报错 “Generating Pods project Abort trap

我的程序出现 abort() 错误,但由于它是程序的加载部分,我无法调试它?

Linux的shell脚本trap信号处理