Access violation after reallocating memory

Advertisements

I get access violation if I’m allocating memory to list->v[list->length]

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char* denumire, * producator;
    int cantitate;
}produs;
typedef struct {
    produs** v;
    int lungime;
    int capacitate;
} Lista;

produs crearePr(char* nume, char* producator, int cantitate)
{
    produs material;   
    material.denumire = (char*)malloc(strlen(nume) + 1);
    strcpy(material.denumire, nume);
    material.producator = (char*)malloc(strlen(producator) + 1);
    strcpy(material.producator, producator);
    material.cantitate = cantitate;
    return material;
}

void creareLi(Lista* lista)
{
    lista->lungime = 0;
    lista->capacitate = 1;
    lista->v = (produs**)malloc(sizeof(produs*) * lista->capacitate);
}

void redim(Lista *l)
{
    l->capacitate *= 2;
    l->v = (produs**)realloc(l->v,sizeof(produs) * l->capacitate);
}

void adauga(Lista *lista, produs p)
{
    if (lista->lungime == lista->capacitate) redim(&lista);
    
    lista->v[lista->lungime] = (produs*)malloc(sizeof(produs));
    *lista->v[lista->lungime] = p;
    lista->lungime++;

}

int main()
{
    Lista lista;
    creareLi(&lista);
    adauga(&lista, crearePr("Zahar", "Tarom", 100));
    return 0;
}

Explanation:

  • crearePr should create a struct produs
  • creareLi should initialize the list, set capacity 1 and length 0
  • redim is called to expand the capacity
  • adauga should add struct produs to list

>Solution :

If you enable warnings in your compiler, you’ll see something like this:

warning: passing argument 1 of 'redim' from incompatible pointer type [-Wincompatible-pointer-types]
   41 |     if (lista->lungime == lista->capacitate) redim(&lista);
      |                                                    ^~~~~~
      |                                                    |
      |                                                    Lista **

That’s telling you something very important. What you have right now causes undefined behavior.

The variable lista is a pointer to the location of your data in memory. You are reinterpreting &redis as that pointer, but now the redis function is going to modify memory where the lista pointer was stored, instead of what it was pointing at.

This will result in some form of memory corruption, as your struct is larger than a pointer and you’re writing into uncharted territory.

Changing the call to redim(lista) will fix this problem.

Leave a ReplyCancel reply