-2

When I complie it, it has segmentation fault at

strcat(arr, cur->texts); which is in dumpTB function.

In main function, when the dumpTB function is called, it should print out like

hello\ngood bye\nworld\n same as what I have typed in newTB function..

Can anyone figure out what the problem is?


I have added the function called deleteTB(TB tb, int from, int to). I'm not just asking like 'Can you do this for me?', i want to know and learn how to fix. I tried from last night.. but still stuck..

Weirdly, I got a seg fault at the same line 'strcat(arr, cur->texts)'. I tried to modify different way and code differently.. but don't know.

Since my input is like, "hello\ngood bye\nworld\n"..

when the deleteTB(list , 0 , 1) is called like this, // (head node is 0)

printbuffer(list) should print like,

POS 0 : world

then, dumpTB(list) should print like,

world.


since i didn't know the rule in here, i have posted pretty much same thing last night which made people annoyed. Sorry for that. And i'm not just asking you guys to do it. I really want to learn.


#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;
}
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Brian Son
  • 13
  • 6
  • Execute debugger immediate. – Martin James Dec 16 '13 at 11:57
  • What is TB set to be? And [do not cast the return of malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). And also use `strdup()`... – Eregrith Dec 16 '13 at 11:58
  • use strdup() for arr in dumpTB function?! – Brian Son Dec 16 '13 at 12:02
  • 1
    Please, don't cast the pointer returned by `malloc`. It's not required in C. In fact, casting the return value of `malloc` [might do more harm than good](http://c-faq.com/malloc/mallocnocast.html) – Elias Van Ootegem Dec 16 '13 at 12:04
  • @BrianSon no, use `strdup` in newTB instead of `malloc` + `strcpy`. Just do `texts = strdup`. Your function `newTB` fails to comply with the sole purpose principle. `newTB` should *only* do *a new TB*, *not* also cut a string by its line feeds and stuff. – Eregrith Dec 16 '13 at 12:17
  • There is never a reason to use strdup, it is a superfluous, non-standard function. There is nothing wrong with using malloc and strcpy. – Lundin Dec 16 '13 at 12:20
  • I don't think replacing `malloc` and `strcpy` lines by one `strdup` line is superfluous. There is nothing wrong with using them but you can't get the sizes or the loop wrong with `strdup`. – Eregrith Dec 16 '13 at 12:38

1 Answers1

0

you are using strcat function. and the first argument is arr which is not null terminated. So use, below code before using strcat

arr[0]='\0';

Also, check for cur->next in the loop like this.

 while(cur->next != NULL)

Also, your releaseTB will give you segfault for the above said reason. change the loop condition to

 while(head->next != NULL) 

Edit

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);

    }
}
  • I tried like you said.. but still doesn't work.. By the way, for the loop part, if i change to while(cur->next != NULL), it doesn't print out anything – Brian Son Dec 16 '13 at 12:08
  • it seems kinda working.. how could you determine which part is wrong as soon as you see the code.. amazing – Brian Son Dec 16 '13 at 12:29
  • As i'm going to add some more functions on it, wanna ask some idea. In order to access to each node, how will you do it? Coz, i'm gonna write a function called swapTB(TB tb, int pos1, int pos2), which swaps pos1 and pos2 of node.(head node is at position 0). – Brian Son Dec 16 '13 at 12:40
  • So.. let the input is same as above code, then when swapTB(list,1,2); is called, then it should print out like "hello" "world" "good bye". then calling it again, swapTB(list,2,1), it should print the original output "hello" "good bye" "world".. – Brian Son Dec 16 '13 at 12:46
  • You try to implement the logic by yourself. If you are not getting, then you let me know... Happy coding!!! –  Dec 16 '13 at 16:10
  • I edited my post, and added new functions. But weirdly, i'm having a seg fault at the same point.. – Brian Son Dec 17 '13 at 05:08
  • Your the logic you have put for swapTB is wrong I believe. On which platform you are working? –  Dec 17 '13 at 05:25
  • I'm working on deleteTB function at the moment.. By the way, swapTB function worked correctly though. – Brian Son Dec 17 '13 at 05:38
  • I tried in several way.. but still can't figure out what the problem is.. help.. :( – Brian Son Dec 17 '13 at 10:29