0

I have a heap corruption and can't find what the reason. Please, can you help? I have some pieces of code where to my mind the error is located. The heap corruption is generated here (see comments below):

 free(rowPermutation);
 fclose(wFile);

So, memory allocation is here:

static int N = 2,**orderOfRows, *columnsPermutation,*tmpRowPermutation,*resultPermutation,
    *u,*v,**sourceMatrix,**patternMatrix,**auxMatrix1,*incidence,*perm;

 static FILE *wFile,*file,*patternFile;

 void allocate2dMemory() {

    int i = 0;

    sourceMatrix = (int**) malloc(N * sizeof(int *));
    auxMatrix1= (int**) malloc(N * sizeof(int *));
    orderOfRows = (int**) malloc(N * sizeof(int*));
    patternMatrix = (int**) malloc(N * sizeof(int*));
    incidence = (int*) malloc(N * sizeof(int));
    columnsPermutation = (int*) malloc(N * sizeof(int));
    tmpRowPermutation = (int*) malloc(N * sizeof(int));
    resultPermutation = (int*) malloc(N * sizeof(int));
    perm = (int*)malloc(N * sizeof(int));

    u = (int*) malloc(N * sizeof(int));
    v = (int*) malloc(N * sizeof(int));

    if ((sourceMatrix == NULL) || (auxMatrix1 == NULL) || (incidence == NULL) || (orderOfRows == NULL) || 
            (columnsPermutation == NULL) || (tmpRowPermutation == NULL) || (u == NULL) || (v == NULL) || (resultPermutation == NULL)) {
            fprintf(stderr, "out of memory\n");
            exit(2);
    }


    for (i = 0; i < N; i++) {
            sourceMatrix[i] = (int*) malloc(N * sizeof(int));
            auxMatrix1[i] = (int*) malloc(N * sizeof(int));
            patternMatrix[i] = (int*) malloc(N * sizeof(int));
            incidence[i] = 0;
            if ((sourceMatrix[i] == NULL) || (auxMatrix1[i] == NULL) || (patternMatrix[i] == NULL) ) {
                            fprintf(stderr, "out of memory\n");
                            exit(2);
            }
    }

}

Open files:

 void openFile(char* filename) {
    if ((file = fopen(filename, "r")) == NULL) {
            perror("Open error");
            printf("\nPress any key for exit\n\n");
            getch();
            exit(1);
    }


    if ((patternFile = fopen("pattern.dat", "r")) == NULL) {
            perror("Open error");
            printf("\nPress any key for exit\n\n");
            getch();
            exit(1);
    }

    if ((wFile = fopen("out.txt", "w")) == NULL) {
            perror("Open error");
            printf("\nPress any key for exit\n\n");
            getch();
            exit(1);
    }

Then I close some of them ("wFile" is the file for writing):

  fclose(file);
  fclose(patternFile);

Change rows order:

  void changeRowOrder(int *computation,int **matr) {

    fprintf(wFile,"Make row permutation\n");

    int i,j;

    for (i = 0; i < N; ++i) {
            orderOfRows[computation[i]] = matr[i];
    }
    fputs("\n",wFile);
}

Change the order of columns:

   int **destMatrix = (int**) malloc(N * sizeof(int *));

    if ((destMatrix == NULL)) {
            fprintf(stderr, "out of memory\n");
            exit(2);
    }

    for (i = 0; i < N; i++) {
            destMatrix[i] = (int*) malloc(N * sizeof(int));

            if (destMatrix[i] == NULL) {
                    fprintf(stderr, "out of memory\n");
                    exit(2);
            }
    }

    for(i = 0; i < N; ++i) {
            // save permutation
            resultPermutation[perm[i]] = i;
            for(j = 0; j < N; ++j) {
                    destMatrix[i][j] = orderOfRows[i][perm[j]];
            }
    }

    fprintf(wFile,"Now result permutation is: \n");
    printArray(resultPermutation);

    for(i = 0; i < N; ++i) {
            free(sourceMatrix[i]);
    }
    free(sourceMatrix);

    sourceMatrix = destMatrix;

I need static pointers to see them in all my programm. Here is located another code where an error can exist:

The code below is at the beginning of the programm.

    int res,i,j;
    char c[25],f[25],g;

    int *rowPermutation = (int*)malloc(N*sizeof(int));

    openFile("inb.dat");
    fscanf(file,"%s %s %d %d",&c,&f,&N,&i);
    allocate2dMemory();
    getMaxtrix();
    // and so on ...
     free(rowPermutation);
    fclose(wFile);

I don't allocate memory in other place of my programm. I have noticed that memory is corrupted in the "columnsPermutation" array. First, i copy some elements, then the element begin to change. I have noticed it when I used STL container to fix heap corruption (just to know why the arrays differ).

Please,can you find an error? To my mind, I allocate the memory correctly.

enter image description here

trincot
  • 317,000
  • 35
  • 244
  • 286
user565447
  • 969
  • 3
  • 14
  • 29
  • Can you give us the exact error on output? Have you tried using GDB to find anything? Also, can you post the entire functions, not just snippets? – samoz Jan 09 '12 at 20:17
  • 3
    Tangential comment: [You should prefer](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) `x = malloc(N * sizeof(*x))` to `x = (T *) malloc(N * sizeof(T))`. – Oliver Charlesworth Jan 09 '12 at 20:21
  • There is a possible typo at the beginning of your program. Is it possible that your function name is `getMatrix` and not `getMaxtrix`? – Marlon Jan 09 '12 at 20:23
  • Problem more likely to be the code that writes to these arrays than the allocation. – David Heffernan Jan 09 '12 at 20:30
  • @oli-charlesworth, you're right, but `malloc` is sometimes defined as returning `char *`, which forces people to cast. But avoiding a cast is always better, if possible. – ugoren Jan 09 '12 at 20:30
  • 1
    @ugoren If `malloc` is declared as returning `char*` then that's an error. Real compilers and libraries don't do that. – David Heffernan Jan 09 '12 at 20:32
  • 1
    @ugoren: Indeed, but that's pre-standard C, so I wouldn't bother too much with that... – Oliver Charlesworth Jan 09 '12 at 20:34
  • You don't really need static variables. You can put them in a struct and pass them around as parameters to functions. – David Heffernan Jan 09 '12 at 20:39
  • @OliCharlesworth: You should have a bot automatically post that comment in every [C] question with that pattern! – tomlogic Jan 09 '12 at 20:45
  • We miss some stuff from your code to be able to tell (e.g. where is matr, perm, ... etc are allocated/initialized/set). Would you mind posting your whole C file on a pastebin somewhere or here? – Quentin Casasnovas Jan 09 '12 at 20:55
  • @auxv: No, the OP should debug this, and then come back with a specific question once (s)he's isolated the problem (using GDB+Valgrind or equivalent). Posting a whole bunch of code and then asking "where's the bug?" is not a suitable question for SO... – Oliver Charlesworth Jan 09 '12 at 21:06

2 Answers2

2

What is the value of N when you call the malloc() for rowPermutation? Because I see you're getting the value of N from the fscanf() after allocating memory to rowPermutation using malloc() for N elements. If N is not properly initialized, it may contain a garbage value.

int *rowPermutation = (int*)malloc(N*sizeof(int));
// What is the value of N when executing the above code?

openFile("inb.dat");
fscanf(file,"%s %s %d %d",&c,&f,&N,&i);
// N is obtained after malloc'ing memory to rowPermutation

OTOH, it is good to use tools like valgrind to check for memory leak issues.

Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98
  • see the code attentively, static N = 2; – user565447 Jan 10 '12 at 05:08
  • @user565447 apologies.. I may have missed it. You code was split into multiple chunks.. N was initialized in the first block and the `malloc()` and `free()` for `rowPermutation` was done in the last block. OTOH, did you get a chance to use valgrind to check the memory leak?! – Sangeeth Saravanaraj Jan 10 '12 at 05:12
  • thanks for comment, I haven't done it. The reason is that I use OS windows.Is there any profiles like this for windows, because I haven't UNIX in the laboratory – user565447 Jan 10 '12 at 05:23
  • @user565447 If you are using `windows`, then please use [cygwin](http://www.cygwin.com/) (`Cygwin` is a collection of tools which provide a `Linux` look-and-feel environment for `Windows`) and then you can install `valgrind` in that! – Sangeeth Saravanaraj Jan 10 '12 at 05:50
0

Even for the best programmers mistakes related to heap corruption are common. Instead of going line by line, I propose to download valgrind from valgrind.org and follow a quick how to that comes with that program. Valgrdind is free and comes with the most flavors of Linux.

A commercial alternative is insure++ from parasoft.com.

Production code should always be checked against memory problems, thereafter it is a good opportunity to install a tool for that reason.

Regarding your program:

if ((sourceMatrix[i] == NULL) || (auxMatrix1[i] == NULL) || (patternMatrix[i] == NULL) ) {

If some of those pointers is NULL you are exiting. Before calling exit(2) you need to free pointers that are already allocated. Every time an exception ( pointer == NULL ) happens you also need to take care (free) that pointers that are allocated before the exception.

cateof
  • 6,608
  • 25
  • 79
  • 153
  • Hm, will the operating system do it instead of me? I need this pointers in all my programm, but if there is an error, I give the OS an opportunity to free memory – user565447 Jan 10 '12 at 05:16