3

This code works when these lines are commented out as shown.But if those 4 lines are uncommented,there is a SIGSEV fault-string 's' does not get initialised . How is it that a function call works at its own but not in a loop ? when the loop has nothing to do with the function's data.

  #define yes 1
    #define no 0
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    char *readline(FILE *f){
        char *buff=NULL,*newbuff=NULL,c;
        int buf_sz=1,len=0;
        int keep_going=yes;
        while(keep_going){
            c=fgetc(f);
            if(c==EOF || c=='\n'){
                keep_going=no;
                break;
            }
            if(len==buf_sz-1 && keep_going!=no){
                if(!buff){
                    buf_sz=512;
                    newbuff=malloc(buf_sz);
                }
                else{
                    buf_sz*=2;
                    newbuff=realloc(buff,buf_sz);
                }
                buff=newbuff;
            }
            buff[len++]=c;
        }
        return buff;
    }
    int main(){
        char *s;
        int l,left_mid,right_mid,lp,rp,change=no;
    //  int n;
    //  scanf("%d",&n);
    //  while(n--){
        s=readline(stdin);
        l=strlen(s);
            printf("%d",l);
        //}

            return 0;

          }
6
  • 1
    You fail to nul-terminate the buffer when jumping outof the loop. BTW: the loop can be simplified a lot. BTW: realloc(NULL, ...) works just like malloc, so you could omit that extra condition. Commented Jan 2, 2014 at 21:29
  • @wildplasser but it works fine without the loop Commented Jan 2, 2014 at 21:33
  • welcome to the world of undefined behavior Commented Jan 2, 2014 at 21:37
  • 1
    A blank line results in readline returning NULL, which then immediately crashes in strlen. If the first line with n has nothing else on it, that will be a blank line... Commented Jan 2, 2014 at 21:58
  • @ChrisDodd SO how to read stdin 'n' times if not this way? Commented Jan 2, 2014 at 22:06

1 Answer 1

1
  1. buff needs to be null-terminated.

  2. scanf("%d", &n); keeps the newline.

  3. The buffer is not secured when only a newline is entered.


example to fix

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

char *readline(FILE *f){
    char *buff=NULL,*newbuff=NULL;
    int c;
    int buf_sz=512,len=0;
    buff=malloc(buf_sz);
    if(!buff) return NULL;
    while(EOF != (c=fgetc(f)) && c != '\n'){
        if(len == buf_sz -1){
            buf_sz*=2;
            newbuff=realloc(buff,buf_sz);
            if(newbuff==NULL){
                free(buff);
                return NULL;
            }
            buff=newbuff;
        }
        buff[len++]=c;
    }
    buff[len]='\0';

    return buff;
}

int main(){
    char *s;
    int n, l;
    scanf("%d%*c",&n);
    while(n--){
        s=readline(stdin);//check return value
        l=strlen(s);
        printf("%d\n", l);
        free(s);
    }
    return 0;

}
Sign up to request clarification or add additional context in comments.

3 Comments

could you elaborate please?
@piyukr newline are remaining to be consumed when you enable the scanf. So, when readline is called, a state in which you enter a new line only.
@piyukr NULL is returned in the buffer is not secured so exit the loop immediately when readline is performed on the new line only. strlen (NULL) causes an exception.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.