0

I'm trying to use realloc function in C, to dynamically operate on a char array of strings (char**). I usually get a realloc():invalid old size error after 41st cicle of the for loop and I really can't understand why. So, thanks to everyone who will help me ^-^

[EDIT] I'm trying to make the post more clear and following your advices, as a "new active member" of this community, so thank you all!

typedef struct _WordsOfInterest {  // this is in an header file containing just
    char **saved;                  // the struct and libraries
    int index;
} wordsOfInterest;


int main() {
    char *token1, *token2, *save1 = NULL, file[LEN], *temp, *word, **tokenArr;
    int n=0, ch,ch2, flag=0, size, init=0,position,currEdit,init2=0,tempEdit,size_arr=LEN, 
        oldIndex=0,totalIndex=0,*editArr,counterTok=0;
    wordsOfInterest toPrint;
    char **final;
    toPrint.index = 0;
    toPrint.saved = malloc(sizeof(char*)*LEN);
    editArr = malloc(sizeof(int)*LEN);
    tokenArr = malloc(sizeof(char*)*LEN);
    final = malloc(sizeof(char*)*1);


    // external for loop 
    for(...) {
        tokenArr[counterTok] = token1;
        // internal while loop
        while(...) {
            // some code here surely not involved in the issue
        } else {
            if(init2 == 0) {
                currEdit = config(token1,token2);
                toPrint.saved[toPrint.index] = token2;
                toPrint.index++;
                init2 = 1;
            } else {
                if((abs((int)strlen(token1)-(int)strlen(token2)))<=currEdit) {
                    if((tempEdit = config(token1,token2)) == currEdit) {
                        toPrint.saved[toPrint.index] = token2;
                        toPrint.index++;
                        if(toPrint.index == size_arr-1) {
                            size_arr = size_arr*2;
                            toPrint.saved = realloc(toPrint.saved, size_arr);
                        }
                    } else if((tempEdit = config(token1,token2))<currEdit) {
                        freeArr(toPrint, size_arr);
                        toPrint.saved[toPrint.index] = token2;
                        toPrint.index++;
                        currEdit = tempEdit;
                    }
                }
            }
            flag = 0;
            word = NULL;
            temp = NULL;
            freeArr(toPrint, size_arr);
        }
    }
    editArr[counterTok] = currEdit;
    init2 = 0;
    totalIndex = totalIndex + toPrint.index + 1;
    final = realloc(final, (sizeof(char*)*totalIndex));
    uniteArr(toPrint, final, oldIndex); 
    oldIndex = toPrint.index;
    freeArr(toPrint,size_arr);
    fseek(fp2,0,SEEK_SET);
    counterTok++;
}
CommuBoi
  • 1
  • 1
  • 2
    `realloc(toPrint.saved, size_arr)` too small. Post a [mcve]. – chux - Reinstate Monica Sep 01 '21 at 16:32
  • You have an extra `}` at the end. – Barmar Sep 01 '21 at 16:32
  • You have an `else` with no `if`. – Barmar Sep 01 '21 at 16:33
  • What is `toPrint`? What are its members? How is it initialized? And have you tried to find some cases that replicates the problem always? Have you tried to debug? Have you tried to catch crashes in a debugger? – Some programmer dude Sep 01 '21 at 16:33
  • Also remember that like `malloc`, the size given to `realloc` is the size in *bytes*, not "array elements". – Some programmer dude Sep 01 '21 at 16:33
  • The error you're getting suggests that you caused undefined behavior somewhere in the program -- buffer overflow, using an uninitialized pointer, etc. – Barmar Sep 01 '21 at 16:34
  • "_probably caused by an unknown character inserted_" What is an "unknown character" and why would it cause a seg-fault? A seg-fault is caused when you access memory not mapped to the current process. If you think it is irrelevant however, don't mention it - it will only invite unwanted comments like this one. – Clifford Sep 01 '21 at 16:36
  • Use a debugger, inspect the parameters you are passing to `realloc()`, check they are valid and as expected. Posting debugging questions to SO is a slow debugging process, and more or less asking others to do what I have suggested for you - except we can't because you have elided the code. Both your seg-fault and your `realloc()` error however are likely caused by the same heap corruption and the code clearly has issues that may not be apparent in your elided fragment. – Clifford Sep 01 '21 at 16:38
  • There are compiler errors even after adding some library headers, such as *`LEN`: undeclared identifier*. Please post a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) as text, the shortest *complete* code that shows what you have tried. The best way to do that is by copy/paste, after you check it does exhibit the behaviour described. – Weather Vane Sep 01 '21 at 16:47
  • For this line `final = realloc(final, (sizeof(char*)*totalIndex));` it gives *warning: `realloc`: pointer mismatch for actual parameter 1*. – Weather Vane Sep 01 '21 at 16:50
  • 1
    Try doing e.g. `realloc(toPrint.saved, sizeof(*toPrint.saved) * size_arr)` instead. – Some programmer dude Sep 01 '21 at 16:50
  • Question: which realloc gives you the error? `toPrint.saved = realloc(toPrint.saved, size_arr)` or `final = realloc(final, (sizeof(char*)*totalIndex));`? Have you considered [realloc](https://en.cppreference.com/w/c/memory/realloc) does not behave well when you ask for a size of 0. Finally I had some dynamic allocation issues lately and discovered Valgrind which is a very powerful tool to track these. You might want to give it a try: [here](https://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks) is a quick way to get started with it. – LNiederha Sep 01 '21 at 17:04
  • When somebody writes something like _// some code here surely not involved in the issue_ He is making a mistake and just going against the [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) recommendation. Please read it and see why we recommend you not to obviate anything. – Luis Colorado Sep 07 '21 at 11:21

1 Answers1

0

You start with final uninitialized.

        char **final;

change it to:

        char **final = NULL;

Even if you are starting with no allocation, it needs a valid value (e.g. NULL) because if you don't initialize a local variable to NULL, it gets garbage, and realloc() will think it is reallocating a valid chunk of memory and will fail into Undefined Behaviour. This is probably your problem, but as you have eliminated a lot of code in between the declaration and the first usage of realloc, whe cannot guess what is happening here.

Anyway, if you have indeed initialized it, I cannot say, as you have hidden part of the code, unlistening the recommendation of How to create a Minimal, Reproducible Example .

There are several reasons (mostly explained there) to provide a full but m inimal, out of the box, failing code. This allows us to test that code without having to provide (and probably solving, all or part) the neccesary code to make it run. If you only post a concept, you cannot expect from us complete, full running, and tested code, degrading strongly the quality of SO answers.

This means you have work to do before posting, not just eliminating what you think is not worth mentioning.

  • You need to build a sample that, with minimum code, shows the actual behaviour you see (a nonworking complete program) This means eliminating everything that is not related to the problem.
  • You need (and this is by far more important) to, before sending the code, to test it at your site, and see that it behaves as you see at home. There are many examples that, when eliminated the unrelated code, don't show the commented behaviour.
  • ...and then, without touching anymore the code, send it as is. Many times we see code that has been touched before sending, and the problem dissapeared.

If we need to build a program, we will probably do it with many other mistakes, but not yours, and this desvirtuates the purpose of this forum.

Finally, sorry for the flame.... but it is necessary to make people read the rules.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31