Thread: Some help with realloc

  1. #1
    Registered User
    Join Date
    Oct 2008
    Location
    Illinois
    Posts
    7

    Some help with realloc

    Hi all, I'm new to C after working with PHP and other languages for years. I'm taking a class and having some problems with an assignment. In the following code, everything works fine until I try to realloc a size of 100. Then I get an "invalid next size" error. Any suggestions?

    Code:
    //CS306 Lab 1 lab1.c
    //Author: Chris Wiegman
    //Will search through file or
    //standard input for a given string
    //
    //Call as:
    // mygrep STRING [FILE...]
    //Based on:
    // Solution to Lab #1 in CS 306, Fall 2008
    // Author: Norman Carver
    
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #define FILE_BUFFER_SIZE 1024
    #define INIT_BUFF_SIZE 50
    #define INC_BUFF_SIZE 10
    
    char *get_next_line(int fd);
    int get_next_char(int fd);
    int grep_open_file (char *search_string,int fd,char *file_pathname, int print_file);
    
    int main(int argc, char *argv[]) {
    	char *needle, *file_pathname;
    	int i, fd, status = EXIT_SUCCESS;
    
    	if (argc < 2) {
    		fprintf(stderr,"Usage: mygrep STRING [FILE...]\n");
    		return EXIT_FAILURE;
    	}
    
    	needle = argv[1];
    
    	if(argc == 2) {
    		file_pathname = "stdin";
    		fd = 0;
    		grep_open_file(needle,fd,file_pathname,0);
    	} else {
    		for (i=2; i<argc; i++) {
    			file_pathname = argv[i];
    			fd = open(file_pathname,O_RDONLY);
    			if (errno > 0) {
    				fprintf(stderr,"%s: Error opening file %s: %s\n", argv[0], file_pathname, strerror(errno));
    				status = EXIT_FAILURE;
    			} else {
          			grep_open_file(needle,fd,file_pathname,argc>3);
          			close(fd);
          		}
    		}
    	}
      return status;
    }
    
    int grep_open_file(char *needle, int fd, char *file_pathname, int print_file) {
    	char *haystack;
    
        while ((haystack = get_next_line(fd)) != NULL) {
        	if (strstr(haystack,needle) != NULL) {
        		if (print_file) {
        			printf("%s:%s\n",file_pathname,haystack);
        		} else {
        			printf("%s\n",haystack);
        		}
        	}
        }
    
        if (errno > 0) {
        	fprintf(stderr,"Error reading from file %s: %s\n", file_pathname, strerror(errno));
        	return EXIT_FAILURE;
        }
    
        return EXIT_SUCCESS;
    }
    
    char *get_next_line(int fd) {
    	static char *line_buff;
    	char *temp_buff;
    	int buff_pos, next_char, chars_left, buff_size;
    	static int string_complete;
    
    	if (string_complete == 1 && line_buff == NULL) {
    		free(line_buff);
    	}
    
    	buff_size = INIT_BUFF_SIZE;
    	chars_left = buff_size;
    	line_buff = malloc(buff_size);
    
    	buff_pos = 0;
    
    	while ((next_char = get_next_char(fd)) != '\n' && next_char != EOF) {
    		//printf("%s: %d\n","chars_left",chars_left);
    		if (chars_left > 0) {
    			chars_left--;
    		} else {
    			buff_size = buff_size + INC_BUFF_SIZE;
    			printf("%d\n",buff_size);
    			//printf("%s\n",line_buff);
    			temp_buff = line_buff;
    			line_buff = realloc(line_buff,buff_size);
    			if (line_buff == NULL) {
    				string_complete = 1;
    				return NULL;
    			}
    			chars_left = INC_BUFF_SIZE;
    		}
    		line_buff[buff_pos++] = next_char;
    	}
    
    	line_buff[buff_pos] = '\0';
    	string_complete = 1;
    
    	if (next_char == EOF && (buff_pos == 0 || (errno > 0))) {
    		return NULL;
    	} else {
    		return line_buff;
    	}
    }
    
    int get_next_char(int fd) {
    	static char char_buff[FILE_BUFFER_SIZE];
    	static int char_count, bytes_left,pos;
    	if (bytes_left == 0) {
    		char_count = read(fd, char_buff, FILE_BUFFER_SIZE);
    		bytes_left = char_count;
    		pos = 0;
    	}
    	if (bytes_left != 0) {
    		bytes_left--;
    		return char_buff[pos++];
    	} else {
    		return EOF;
    	}
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You're getting a runtime error? I don't recognize invalid next size as a possible result from realloc. If it fails, you should just get a NULL pointer.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    Illinois
    Posts
    7
    That's what I would have thought, but that's not what is happening. I've tried testing for null with some print statements, yet they never get executed.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well: what OS are you on, and what does it say, exactly?

  5. #5
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    If the while loop ends with chars_left == 1, line_buff[buff_pos] = '\0'
    is guaranteed to generate an overflow.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    Illinois
    Posts
    7
    Got it. I removed
    Code:
    chars_left = INC_BUFF_SIZE;
    and it seems to be working fine. Thanks all!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. did i understood right this explantion of realloc..
    By transgalactic2 in forum C Programming
    Replies: 3
    Last Post: 10-24-2008, 07:26 AM
  2. writing a pack-style function, any advices?
    By isaac_s in forum C Programming
    Replies: 10
    Last Post: 07-08-2006, 08:09 PM
  3. using realloc
    By bobthebullet990 in forum C Programming
    Replies: 14
    Last Post: 12-06-2005, 05:00 PM
  4. segfault on realloc
    By ziel in forum C Programming
    Replies: 5
    Last Post: 03-16-2003, 04:40 PM
  5. Realloc inappropriate for aligned blocks - Alternatives?
    By zeckensack in forum C Programming
    Replies: 2
    Last Post: 03-20-2002, 02:10 PM