-1

I get a segfault after calling mygets(). Here is my code:

    #include <termios.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct _charlist{
        char ch;
        struct _charlist *next;
    }charlist;
    
    static struct termios old, new;
    void mygets(char** p);
    char getche(void); 
    char getch_(int echo);
    void resetTermios(void);
    void initTermios(int echo);
    
    
    int main(void){
        char *p;
        
        printf("\nWho loves orange soda?: ");
        mygets(&p);
        printf("'%s' loves orange soda!", p);
    }
    
    
    void mygets(char** p){
        char c;
        charlist *root, *curr;
        unsigned i, count=0;
    
        root=NULL;
    
    while((c = getche()) != '\n'){      
    
        count++;    
        if(!root){ 
            root = (charlist*) malloc(sizeof(charlist));
            root->ch = c;
                root->next = NULL;
                curr = root;
            }
    
            else{
                curr
->next = (charlist*) malloc(sizeof(charlist));
                curr->next->ch = c;
                curr->next->next = NULL;
                curr = curr->next;
            }
        }
    
        //now request string space.
        *p = (char*) malloc((count+1)*sizeof(char));
    
        printf("\np is now malloced");      //This line doesn't get printed!
        
        //move linked list into string space.
        curr = root;
        for(i=0; i<=count; i++){
            *p[i] = curr->ch;
            curr = curr->next;
        }
    
        //null-terminate the string.
        *p[i] = '\0';
    
    }

Can someone tell me why I get a segfault?

I can't post this question unless the ratio of code to question is lower than some arbitrary threshold. Therefore, there now follows the first paragraph of Alice in Wonderland, for your consideration.

Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice 'without pictures or conversation?'

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Korgan Rivera
  • 495
  • 3
  • 9

3 Answers3

4

When func is called, it is passed a copy of the local variable p in main. This copy is then assigned the malloced area in func. The original p in the main is never modified, so its contents remain undefined, causing a segmentation fault when printf dereferences p in order to print the string.

You may want func to return a char* pointing to the newly malloc'd area.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
1

You pass the argument to the function by value. So according to the function declaration

void func(char* p);

parameter p is a local variable of the function that will be destroyed after exiting the function. Any changes of the local variable do not influence on the argument.

You could define the function the following ways

char * func(){
    unsigned count = 10;
    char *p = (char*) malloc(sizeof(char)*(count+1));

    //p is given a string after this, but problem is the above line.

   return p;
}

and call it as

p = funct();

or

void func(char ** p){
    unsigned count = 10;
    *p = (char*) malloc(sizeof(char)*(count+1));

    //p is given a string after this, but problem is the above line.
}

and call it as

func( &p );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The problem is with:

*p[i] = curr->ch;

Should be:

(*p)[i] = curr->ch;

You want to access the i'th character of where p is pointing to. Not dereference the ith pointer in an array of pointers.

Same problem with *p[i] = '\0'; later.

Also you did not malloc enough space, as your loop writes count + 1 characters and then you write an extra null terminator, so you should either malloc count + 2 or adjust your loop to finish at i<count, not i<=count. (probably the latter).

Also, it'd be useful to check curr != NULL before dereferencing it, so that if you do have an off-by-one error then you don't get undefined behaviour.

M.M
  • 138,810
  • 21
  • 208
  • 365