0

I'm a beginner in C. I'm trying to implement a vector in C. After successfully compiling the program with GCC. I get this error on the command line while I tried to run it. I use GCC with wsl2 Linux ubuntu.<GCC (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0>
Here's part of my code.
Vector.h

#pragma once

typedef struct DynamicArray
{
    int* data;
    int size;
    int capacity;
    int is_resizeable; //resizeable = 0; unresizeable = 1;
} Vector;

void init_Vector
    (Vector* self, int capacity, int is_resizeable, int default_value);  //Initlizing a Vector
    
void finalize_Vector
    (Vector** pp);
void fancy_print
    (Vector* self);

I designed a constructor function that allows the user to destroy a vector in the program. Here is a concrete implementation of the two functions.
Vector.c

void init_Vector
    (Vector* self, int capacity, int is_resizeable, int default_value)
{
    self->data = (int*)malloc(capacity * sizeof(int));
    self->is_resizeable = is_resizeable;
    self->capacity = capacity;
    self->size = 0;

    for (int i = 0; i < capacity; i++) 
    {
        self->data[i] = default_value;
        self->size++;
    }
}

void finalize_Vector
    (Vector** pp) 
{
    free(*pp);
    *pp = NULL;
}
void fancy_print
    (Vector* self) 
{
    printf("<CVector Object>: size: %d, capacity: %d, isresizeable: %d, {", self->size, self->capacity, self->is_resizeable);
    
    for (int i = 0; i < self->size; i++) 
    {
        printf("%d", self->data[i]);
        if (i != self->size - 1)
            printf(", ");
    }
    printf("}\n");
}

Then I wrote the main function to test my constructor and destructor functions.
main.c

int main(void) 
{
    Vector v;
    init_Vector(&v, 5, 0, 1);
    fancy_print(&v);
    Vector* p = &v;
    finalize_Vector(&p);
    return 0;
}

GCC is compiled without any warnings or errors. But when I try to run my program, I got this.

<CVector Object>: size: 5, capacity: 5, isresizeable: 0, {1, 1, 1, 1, 1}
double free or corruption (out)
Aborted

I can't find out why there's a "double free or corruption", please help me.

MuxAte
  • 66
  • 1
  • 6
  • 3
    `Vector v;` lives in automatic storage. You don't need to free it. (Actually: you cannot free it, because it was not obtained by malloc) – wildplasser Jul 16 '20 at 12:40
  • Thanks for answering my questions . : - ) And I'm still wondering If I want to free up some memory, do I need free(v.data)? – MuxAte Jul 16 '20 at 12:46
  • Remove the cast (int *) on malloc. https://stackoverflow.com/a/605858/1216776 – stark Jul 16 '20 at 13:14

2 Answers2

4

You're trying to free memory you didn't malloc. And you don't free the one piece of memory you did malloc. In your case you probably meant:

void finalize_Vector(Vector** pp) 
{
    free((*pp)->data);
    (*pp)->data = NULL;
}

If you did mean your original code and wanted to delete the whole vector then it gets hard to control because you can only finalize a malloced vector. Consider:

Vector v;
Vector *v2 = &v;
Vector *v3 = v2;
finalize_Vector(&v2);
// v3 is still pointing at something - should it be valid or not ?

Don't be a 2 star programmer. Use

void finalize_Vector(Vector* pp) 
{
    free(pp->data);
    pp->data = NULL;
}

Which you can use on malloced vectors or auto.

John3136
  • 28,809
  • 4
  • 51
  • 69
  • Appreciate for answering my questions exactly. Thanks a lot. (And I will not use 2 stars again. ( •̀ ω •́ )✧ ) – MuxAte Jul 16 '20 at 12:56
  • If I want to destroy `Vector v`, not just `v.data`, what should I do? Is it possible in C? – MuxAte Jul 16 '20 at 13:01
  • If you do malloc the Vector you can free it. If you don't malloc the vector then you can't. – John3136 Jul 17 '20 at 01:47
0

Basically, "you" are not allocating memory for your vector instance. When you declare

Vector v;

the system allocates memory on the stack. It is NOT user allocated on the heap since you are not using malloc. If you had allocated memory yourself, like this -

Vector *v = (Vector *) malloc(sizeof(Vector));

then this program would work fine.

So, when the program ends (when the stack is popped out), it tries to free the memory that was allocated by the system. But you already free'ed the memory in finalize_Vector. That is the reason you are getting this error.

Basically what you need to do is to either allocate memory to the vector yourself. Like this -

Vector *v = (Vector *) malloc(sizeof(Vector));

and in finalize_vector, free the memory -

void finalize_Vector
    (Vector** pp) 
{
    free(*pp->data);
    free(*pp);
    *pp = NULL;
}

OR

let the system handle the memory allocation for the vector by just changing the finalize_vector

void finalize_Vector
    (Vector* pp) 
{
    free(pp->data);
}
buchipper
  • 606
  • 4
  • 16
  • When initializing, I just want its internal data pointer to point to a new `malloced` int-type array, can I just `self->data = (int *) malloc(sizeof(int) * capacity);` ? – MuxAte Jul 16 '20 at 13:11
  • Yes. I don't see any problem with the init_Vector function, since there you are just allocating memory for the data pointer. – buchipper Jul 16 '20 at 13:15