0

I've stumbled upon following problem: I wrote a program in C, which functions as a variation of Mergesort, just with forking. For this problem, I wrote a function which reads exactly one line from some input stream specified by a parameter, adds a '\0' at the end, and returns a boolean, indicating whether a newline character exists or not. The source code is below:

static bool getInputLine(FILE *f, char **input, int *size_in) {                                                                                               
    int size = 0;                                                                                                                                             
    char todo;                                                                                                                                                
                                                                                                                                                              
    do {                                                                                                                                                      
        if((*input = realloc(*input, (size + 1) * sizeof(char))) == NULL) exitWithStatus(EXIT_FAILURE, "reallocing FAILED");                                  
        todo = fgetc(f);                                                                                                                                      
        if(todo == EOF) break;                                                                                                                                
        (*input)[size] = todo;                                                                                                                                
        if(todo == '\n' && size == 0){                                                                                                                        
            fprintf(stdout, "\n");                                                                                                                                                                                                                                                            
            break;                                                                                                                                            
        }                                                                                                                                                     
        size++;                                                                                                                                               
    } while(todo != '\n');                                                                                                                                    
                                                                                                                                                              
    if((*input = realloc(*input, (size+1) * sizeof(char))) == NULL) exitWithStatus(EXIT_FAILURE, "reallocing FAILED");                                        
                                                                                                                                                              
    (*input)[size] = '\0';                                                                                                                                    
    *size_in = size;                                                                                                                                          
                                                                                                                                                              
    return size == 0 || todo != '\n';                                                                                                                         
}  

The code works for (almost) any input, at least so I thought. For some reason, if a line is greater than exactly 26 chars, I get:

realloc(): invalid next size Aborted (core dumped)

I'm relatively new to C, and this had me confused as ever. Any help is greatly appreciated, thanks in advance!

My OS is Linux Fedora, if that helps in any way. Should you need anything else, please let me know :)

And just fyi, the input String is malloc'd with sizeof(char) before calling the function! It is freed again at exiting the process.

EDIT: Despite help from various sides, I have not been able to solve this issue. I had to generally rethink my strategy to solve the problem as a whole. I suppose it had something to do with global variables being inherited by the forked child processes, and hence borking the heap structs in some way or another. Unfortunately, I lost track of what happened exactly, despite restructuring my code to make it more debug-friendly. Thank you very much for your help regardless! :)

padraig
  • 31
  • 6
  • 'the input String is malloc'd with sizeof(char) before calling the function!' - could you expand(!) on that, 'cos it's a bit worrying.. You likely borked the heap structs, maybe elsewhere in the code, eg. by exceeding array bounds ( – Martin James Dec 10 '22 at 12:24
  • Thank you for your answer, unfortunately I wouldn't know how that would happen, or how I would alteratively solve this issue without mallocing beforehand. In the main function, it looks something like: char *input = malloc(sizeof(char)); int size; getInputLine(stdin, &input, &size); Afterwards, I only use the Strings for strcmp (for sorting) and for fprintf()... – padraig Dec 10 '22 at 12:34
  • 4
    @padraig Please note that descriptions of code are generally unhelpful. Instead you should [edit] your question to *show* your code in the form of a [mcve]. – G.M. Dec 10 '22 at 12:45
  • 2
    `if((*input = realloc(*input, (size + 1) * sizeof(char))) == NULL) exitWithStatus(EXIT_FAILURE, "reallocing FAILED");` all in one line? And you wonder why you can't figure out what's going on? Cramming code into one line like that is extremely bug-prone and makes it hard to debug and literally impossible for your brain to comprehend. If the rest of your code is like that, it's no wonder you can't figure it out: you've made it harder on yourself. – Andrew Henle Dec 10 '22 at 13:20
  • 1
    Better to use `char todo;` --> `int todo;` – chux - Reinstate Monica Dec 10 '22 at 15:05
  • To chux's comment, see https://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc-and-putchar-fputc/35356684#35356684. Basically, with `char todo; todo = fgetc(f);`, your `if (todo == EOF)` will, depending on your platform, either never be true, or sometimes be true for certain valid characters. It really does have to be `int`. You need a type that can store every possible `char` **as well as** the separate value `EOF`. – Nate Eldredge Dec 10 '22 at 16:16
  • Stop thrashing the heap. Use a stack char array (10kb?) to collect the input, then only one `realloc()` to get a persistent buffer to copy the input to... Write better code and move on in life... – Fe2O3 Dec 10 '22 at 19:38

0 Answers0