0

第一次addToEnd()调用它可以工作,但第二次它会使程序崩溃。我一直在尝试调试它,发现它在发生时head->next会发生。我有点困惑,因为它只是被读取,这会使程序崩溃吗?如果是的话,你怎么可能遍历文件?

它似乎适用于某些价值观,entry但不适用于其他价值观。如果两个条目相同并且全部由一个字母组成,则会崩溃。因此,如果调用 addToEnd(head, "aaaaaaaaa") 则调用 addToEnd(head, "aaaaaaaaaa") 程序崩溃,但如果 addToEnd(head, "aaaaaaaa") 然后 addToEnd(head, "aaaaaaaaab") 就可以了。

这是 100% 的所有代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

typedef struct node
{
  char entry[21];
  struct node* next;
} node;

void readDic();
void reverStr(char *str);
bool isInDic(char *reversed);
void addToEnd(node* head, char entry[21]);
unsigned int searchAndDestroy(node **head, char *entry);
void printList(node* head);
int main()
{
    printf("Hello\n");
    readDic();
    printf("Goodbye!");
    return EXIT_SUCCESS;
}

void readDic()
{
    FILE* words;
    char singleLine[21];
    words = fopen("words.txt", "r");
    node* head = malloc(sizeof(node));
    fscanf(words, "%20s", head->entry);//need to do this initially
    head->next = NULL;
    printf("here 0");

    printf("here 0.1");
    if(words == NULL)
        exit(EXIT_FAILURE);
    printf("here 0.5");
    while(fscanf(words, "%20s", singleLine) == 1)assigned input terms
    {
        printf("\nhere 0.6\n|%s|", singleLine);
        addToEnd(head, singleLine);//problem here
        printf("here 0.7");
        reverStr(singleLine);
        printf("here 1");
        if(isInDic(singleLine)){
            printf("here 2");
            searchAndDestroy(&head, singleLine);
            printf("here 3");
        }
    }
    printf("here 4");
    fclose(words);
    printList(head);
    printf("here 5");
}

//http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
/* PRE: str must be either NULL or a pointer to a
 * (possibly empty) null-terminated string. */
void reverStr(char *str)
{
    char temp, *end_ptr;

    /* If str is NULL or empty, do nothing */
    if(str == NULL || !(*str))
        return;

    end_ptr = str + strlen(str) - 1;

    /* Swap the chars */
    while( end_ptr > str )
    {
    temp = *str;
    *str = *end_ptr;
    *end_ptr = temp;
    str++;
    end_ptr--;
  }
}

bool isInDic(char* reversed)
{
    FILE* words;
    char singleLine[21];

    words = fopen("words", "r");
    if(words == NULL)
        exit(EXIT_FAILURE);
    while(fscanf(words, "%20s", singleLine) == 1)//the length of the string has to be 1 less than declared size for the newline character
    {
        //printf("singline: %s reversed: %s\n", singleLine, reversed);
        if(strcmp(singleLine, reversed) == 0)//strcmp returns 0 if both cstrings are equal
            return true;
    }
    fclose(words);
    return false;
}

void addToEnd(node* head, char entry[21])
{
    printf("hi");
    //printf("\naddress of next %p\n", (void *)head->next);
    while(head->next != NULL)//just reading head->next screws it up
        head = head->next;
    printf("in addToEnd 2\n");
    node* last = (node*)malloc(sizeof(node));
    printf("in addToEnd 3\n");
    head->next = last;
    printf("in addToEnd 4\n");
    strcpy(last->entry, entry);
    printf("in addToEnd 5\n");
    last->next = NULL;
    printf("in addToEnd 6\n");
}

unsigned int searchAndDestroy(node **head, char *entry)
{
    unsigned int count = 0;

    while(*head)
    {
        node *del;
        if(strcmp((*head)->entry, entry))
        { //this node stays
            head = &(*head)->next;
            continue;
        }
        /* this node goes
        at this point head MUST point to the pointer that points at the node to be deleted
        */
        del = *head;
        *head = (*head)->next;
        free(del);
        count++;
    }
    return count; //number of nodes deleted
}

void printList(node* head)
{
    printf("\nprinting everything\n");
    if(head != NULL)
    {
        while(head->next != NULL)
        {
            printf("%s", head->entry);
            head = head->next;
        }
        printf("%s", head->entry);
    }
}

头部设置的答案是正确的,null但我看不出在哪里?

4

2 回答 2

1

三件事之一:

  1. 如果 head 为 NULL,则此代码将在您提到的那一行崩溃。

  2. 如果 last->entry 被定义为 char* 你需要说 'last->entry = strdup(entry)

  3. 如果 last->entry 的 sizeof 小于 21,您的 strcpy 将溢出它,这将导致未定义的行为。

好的,根据您最近的编辑,当您第二次调用此函数时,我断言 head 为空或垃圾。

于 2013-09-30T17:09:56.023 回答
1

创建时head,您不会设置head->nextNULL.

于 2013-09-30T17:14:52.320 回答