0

Some starters:

creating a dynamic array of a data structure called fractions. Fractions has functions for setting, printing, intiting etc.

I kept getting an error for double freeing or corruption, along with a lot of gibberish from the memory map. This is the error from the output:

double free or corruption (top): 0x0000000001976010 *

I get that it is being freed/deleted twice but here is the code that generates the error:

#include <stdio.h>
#include <stdlib.h>
#include "fraction.h"

main() {
    long long int size = 0;
    long long int capacity = 10;
    int FSize = sizeof(struct fraction);
    struct fraction* array = NULL;
    struct fraction in;
    array = (struct fraction*)malloc(FSize * capacity);
    if (array == NULL) {
        printf("MALLOC DID NOT WORK\n");
        exit(1);
    }
    int i = 0;
    for (i = 0; i < 17; i++) {
        if (size == capacity) {
            capacity = capacity * 2;
            struct fraction* temp = NULL;
            temp = (struct fraction*)realloc(array, FSize * capacity);
            //  free(array);
            array = temp;
            free(temp);
        }
        SetFrac(&in);
        array[size++] = in;
    }
    printf("IT MADE IT HERE >>>>>>>>>>>>>>>>>> \n");
    getchar();
    for (i = 0; i < size; i++) {
        struct fraction t = array[i];
        PrintFrac(&t);
    }
    free(array);
    return 0;
}

Here is the code that works

#include <stdio.h>
#include <stdlib.h>
#include "fraction.h"

main() {
    long long int size = 0;
    long long int capacity = 10;
    int FSize = sizeof(struct fraction);
    struct fraction* array = NULL;
    struct fraction in;
    array = (struct fraction*)malloc(FSize * capacity);
    if (array == NULL) {
        printf("MALLOC DID NOT WORK\n");
        exit(1);
    }
    int i = 0;
    for (i = 0; i < 17; i++) {
        if (size == capacity) {
            capacity = capacity * 2;
            struct fraction* temp = NULL;
            temp = (struct fraction*)realloc(array, FSize * capacity);
            //  free(array);
            array = temp;
            free(temp);
        }
        SetFrac(&in);
        array[size++] = in;
    }
    printf("IT MADE IT HERE >>>>>>>>>>>>>>>>>> \n");
    getchar();
    for (i = 0; i < size; i++) {
        struct fraction t = array[i];
        PrintFrac(&t);
    }
    //    free(array);
    return 0;
}

Am I using the free() function wrong?

NetVipeC
  • 4,402
  • 1
  • 17
  • 19
  • You are assigning `array = temp` then freeing `temp`. Since `array` is the same value, you have also freed, in effect, `array`. But then you proceed to use `array` after it was freed, which is bad. Why are you freeing it right after obtaining it with `realloc`? – lurker Sep 16 '14 at 19:56

4 Answers4

1

array and temp have the same pointer address, so when you free temp, array will be freed also

Anis_Stack
  • 3,306
  • 4
  • 30
  • 53
0

You should only free "array" at the end. You must not free "temp", because you'll continue using the block (array = temp does not maintain a certain "reference count", but simply assigns a pointer).

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
  • I just tried removing free(temp). It worked without any errors. Won't there be a memory leak because the memory located at *temp is not being freed? – user3339931 Sep 16 '14 at 20:00
  • It should not be freed there and then, since the same block is still referenced by `array` and you are still using it through that pointer. At the end, when you are not accessing the memory anymore, it can safely be freed. – Rudy Velthuis Sep 16 '14 at 20:20
0

After calling free, you should not dereference the freed memory, which you are doing by using array[size++].

You should not free() on temp there, because you are using array later.

Your final commented out free() would be the only one that would be correct, although the program should run fine with out it.

Michael Chinen
  • 17,737
  • 5
  • 33
  • 45
  • So do I not free temp? – user3339931 Sep 16 '14 at 20:00
  • 1
    Indeed, you should not free temp. `array` is a copy of the pointer, so it points to the same memory block as `temp` (`array = temp;` does not copy the memory, only the value of the pointer, i.e. the address of the memory block). Since you are still using the memory block (through the pointer `array`), it should not be freed yet. It should be freed *after* use. In other words, you are not freeing `temp`, you are freeing the memory block to which `temp` and, later on, `array` point. You should not do that as long as you are still using it, i.e. not at the time you are doing it in your code. – Rudy Velthuis Sep 16 '14 at 20:15
0

You don't need to free(temp) after realloc temp, just to free(array) the end of main. If you realloc is success,two possibilities:

  1. temp == array (temp point to the same memory)
  2. array is free and temp point to a new memory
Krypton
  • 3,337
  • 5
  • 32
  • 52