C /链表/如何修复分段错误?

时间:2013-12-16 11:54:23

标签: c linked-list segmentation-fault

当我对它进行编译时,它在

处有分段错误

strcat(arr, cur->texts);位于dumpTB函数中。

在main函数中,当调用dumpTB函数时,它应该像

一样打印出来

hello\ngood bye\nworld\n与我在newTB函数中输入的内容相同。

有人能弄明白问题是什么吗?


我添加了名为deleteTB的函数(TB tb,int from,int to)。 我不只是问'你能为我做这个吗?',我想知道并学习如何修复。 我昨晚试了..但还是卡住了..

奇怪的是,我在同一行'strcat(arr,cur->文本)'中遇到了一个段错误。我尝试以不同的方式修改不同的方式和代码..但不知道。

由于我的输入是“hello \ ngood bye \ nworld \ n”..

当像这样调用deleteTB(list,0,1)时,//(头节点为0)

printbuffer(list)应该打印出来,

POS 0:世界

然后,dumpTB(list)应该打印出来,

世界。


由于我不知道这里的规则,我昨晚发布了几乎同样的事情让人们恼火。对不起。而且我不只是要求你们这样做。我真的很想学习。


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

#include "textbuffer.h"

#define MAX_TEXT 256

struct textbuffer {
    char *texts;
    int count;
    TB next;
};

TB newTB (char text[]){
    TB newText = malloc(sizeof(struct textbuffer));
    char *cpy = (char *)malloc(MAX_TEXT * sizeof(char));
    TB head = newText; // Store the first node to return

    strcpy(cpy,text);
    newText->count = 0;
    newText->next = NULL;
    int i = 0;
    int j = 0;

    while( cpy[i] != '\0') {
        if( j == 0) {
            head->texts = (char *)malloc(MAX_TEXT * sizeof(char));
        }
        if(cpy[i] == '\n') {
            head->texts[j] = '\0';
            newText->count++;
            head->next = malloc(sizeof(struct textbuffer));
            head = head->next;
            j = 0;
            i++;
        } else {
            head->texts[j++] = cpy[i++];
        }
    }
    head->next = NULL;
    return newText; 
}

void releaseTB (TB tb) {
    TB head = tb;
    TB tmp;

    while(head != NULL) {
        tmp = head;
        head = head->next;
        free(tmp->texts);
        free(tmp);

    }
}

char *dumpTB (TB tb) {
    if(tb == NULL) {
        return NULL;
    }
    TB cur = tb;
    char *arr = (char *)malloc(MAX_TEXT * sizeof(char));

    while(cur != NULL) {
        if(arr == NULL) {
            strcpy(arr,"");
        }
        strcat(arr, cur->texts);
        if(cur->next != NULL) {
            strcat(arr, "\n");
        }
        cur = cur->next;
    }
    return (arr);
}

int linesTB(TB tb) {
    return (tb->count);
}

void printBuffer(TB tb){
    TB curr = tb;
    int i=0;
    while(curr->next != NULL){
        printf("POS %d : %s\n", i++, curr->texts);
        curr = curr->next;
    }
}

void swapTB(TB tb, int pos1, int pos2) {
    if((pos1 < 0) || (pos2 < 0) || (pos1 > linesTB(tb)-1) || (pos2 > linesTB(tb)-1)) {
        printf("**GIVEN LINES ARE OUT OF RANGE**\n");
        abort();
    }
    TB cur = tb;
    TB head = tb;
    int i = 0;

    char *tmp  = (char *)malloc(MAX_TEXT * sizeof(char));
    tb->texts = cur->texts;
    while( i < pos1) {
        cur = cur->next;
        i++;
    }
    strcpy(tmp, cur->texts);
    cur->texts = NULL;
    i=0;
    while( i < pos2) {
        head = head->next;
        i++;
    }
    cur->texts = head->texts;
    head->texts = tmp;
}

void deleteTB(TB tb, int from, int to) {
    if((from < 0) || (to < 0) || (from > linesTB(tb)-1) || (to > linesTB(tb)-1)) {
        printf("**GIVEN LINES ARE OUT OF RANGE**\n");
        abort();
    }
    TB cur = tb;

    int i = 0;

    for(i = 0; i < from; i++) {
        cur = cur->next;
    }
    while( i <= to ) {
        cur->texts = '\0';
        free(cur->texts);
        //free(cur);
        cur = cur->next;
        i++;
    }
}

int main(int argc, char * argv[]) {
    TB list = NULL;
    list = newTB("hello\ngood bye\nworld\n");

    printf("**THERE ARE %d LINES IN TEXTBUFFER**\n", linesTB(list));
    printBuffer(list);
    printf("**Dumping test**\n");
    printf("%s\n",dumpTB(list));

    printf("**Swapping test**\n");
    swapTB(list, 0, 1);
    printBuffer(list);

    printf("**Deleteing test**\n");
    deleteTB(list, 1, 1);
    printBuffer(list);
    printf("%s\n",dumpTB(list));


    releaseTB(list);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

您正在使用strcat功能。并且第一个参数是arr,它不是空终止的。 因此,在使用strcat

之前使用代码
arr[0]='\0';

另外,请像这样在循环中检查cur->next

 while(cur->next != NULL)

此外,由于上述原因,您的releaseTB会向您segfault提供。 将循环条件更改为

 while(head->next != NULL) 

修改

char *dumpTB (TB tb) {
    if(tb == NULL) {
        return NULL;
    }
    TB cur = tb;
    char *arr = (char *)malloc(MAX_TEXT * sizeof(char)); //VS throws error if we wont cast
    arr[0]='\0'; // Null Terminated 
    while(cur->next != NULL) { // changed to cur->next
        if(arr == NULL) {
            strcpy(arr,"");
        }
        strcat(arr, cur->texts);
        if(cur->next != NULL) {
            strcat(arr, "\n");
        }
        cur = cur->next;
    }
    return (arr);
}

void releaseTB (TB tb) {
    TB head = tb;
    TB tmp;

    while(head->next != NULL) { // Changed to head->next
        tmp = head;
        head = head->next;
        free(tmp->texts);
        free(tmp);

    }
}