Problem in using malloc and realloc

2
int main()
{
    int **matriz;

    f(matriz);

    return 0;
}

void f(int **matriz)
{
    int x, l=1,c=3;

    matriz = (int **) malloc(sizeof (int));
    *matriz = (int *) malloc(3 * sizeof (int));

    printf("Insira o valor de x: ");
    scanf("%d", &x);

    if(x==0)
    {
        c*=2;
        *(matriz) = (int *) realloc(*(matriz),c * sizeof (int));
    }
    else
    {
        l++
        matriz = (int **) realloc(matriz, l* sizeof (int));
        *(matriz) = (int *) malloc(3 * sizeof (int));
    }
}
Well, here is an example of the problem I have had in the implementation of malloc and realloc, basically I start by adding a row and 3 columns to insert certain values then in the first condition I continue to insert in the first row, but in the second condition I already want the values in another row and 3 more columns, this type of implementation always ends up giving me memory error and I do not know how to find the error, if anyone could help thanks.

    
asked by anonymous 11.11.2017 / 15:30

2 answers

0

Here is an example using columns and rows map.c

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

char** mapa;
int linhas;
int colunas;

void liberamapa(){
    for (int i = 0; i < linhas; ++i)
    {
        free(mapa[i]);
    }
    free(mapa);
}
void alocamapa(){
    mapa = malloc(sizeof(char*) * linhas);
    for (int i = 0; i < linhas; ++i)
    {       
        mapa[i] = malloc(sizeof(char) * (colunas +1));
    }
}
void lemapa(){
        FILE* f;

    f = fopen("mapa.txt", "r");
    if(f == 0) {
        printf("Erro na leitura do mapa");
        exit(1);
    }

    fscanf(f, "%d %d", &linhas, &colunas);
    alocamapa();

    for(int i = 0; i < 5; i++) {
        fscanf(f, "%s", mapa[i]);
    }
    fclose(f);
}
int main() {

    lemapa();


    for(int i = 0; i < 5; i++) {
        printf("%s\n", mapa[i]);
    }

    liberamapa();

}

matriz = malloc(sizeof(int*)* linhas);
for (int i = 0; i < linhas; ++i)
{       
    matriz[i] = malloc(sizeof(int) * colunas);
}

file.h

void liberamapa();
void alocamapa();
void lemapa();

map

|--------|
|...|..-.|
|..-|.@..|
|......-.|
|--------|
    
11.11.2017 / 17:50
0

I'll start by answering some of the things you put in the comments:

  

Another thing I saw is the use of boot to NULL which I do not   use

In some cases it becomes necessary, when the code tests if one thing comes to NULL , in others it is good practice. In your example you could have declared the array with initial value NULL , which would even solve one of the compiler warnings:

int main()
{
    int **matriz = NULL;
    f(matriz); 
    ...
}

Although not necessary for the logic you have, it makes it clear what value you start with. When you do f(matriz) you are passing a copy of the pointer that has on main which causes the allocation within the f function does not change this pointer, which is incorrect.

See this question I answered exactly the same problem and its solution

  

The code I put in is just an example of the code that I have had   problems

The example you put in is a bit obscure, and difficult to decipher what you were supposed to do (even because it does not have an expected result), so it's hard to help in your real doubts. It would be better to have put a portion of your actual code.

  

I basically do array = (int *) realloc (array, l sizeof (int));   to add new line

If matriz is a int** and l is the new size, which has already been increased from 1 somewhere, then it would be:

matriz = (int**) realloc(matriz, l * sizeof (int*));
  

and * (array + i) = (int *) malloc (n * sizeof (int)); to add more   columns

Assuming that n is the number of columns of each line is right, but simpler would be to do:

matriz[i] = (int *) malloc(n * sizeof (int));

Moving to the code itself

When it does:

*matriz = (int *) malloc(3 * sizeof (int));

Although it works is a bit strange, and later on the same principle is used incorrectly. In this statement, you want to assign to the first row an array of 3 integers, which would be the columns. Make this clearer by doing:

matriz[0] = (int *) malloc(3 * sizeof (int));

So the realloc that is right is the penultimate:

else
{
    l++
    //-^ falta ;

    matriz = (int **) realloc(matriz, l* sizeof (int)); //<--correto
    *(matriz) = (int *) malloc(3 * sizeof (int)); //<--incorreto
}

The latter should be:

matriz[l-1] = (int *) malloc(3 * sizeof (int));

Or if you want to use pointers as you were using:

*(matriz+l-1)  = (int *) malloc(3 * sizeof (int));

Distinctive example with dynamic rows and columns

Here is a different example with dynamic rows and columns of an array and reallocation for more rows as I was trying to do. I made a different example to be more intuitive and clear, and just focus on the part you want to know.

int main()
{
    int linhas = 2, colunas = 5, i;
    int **matriz = (int **) malloc(sizeof (int*) * linhas); //cria as linhas

    //cria as colunas em cada linha
    for (i = 0; i < linhas; ++i){
        matriz[i] = (int*)malloc(sizeof (int) * colunas);
    }

    //coloca alguns valores e mostra
    matriz[0][1] = 10; 
    matriz[1][3] = 10;
    mostrarMatriz(matriz, linhas, colunas);

    //cria uma nova linha
    matriz = (int**) realloc(matriz, sizeof(int*) * ++linhas);

    //cria as colunas para essa nova linha
    matriz[linhas-1] = (int*)malloc(sizeof (int) * colunas);

    //atribui um valor na nova linha e volta a mostrar o resultado
    matriz[linhas-1][0] = 5;
    mostrarMatriz(matriz, linhas, colunas);

    return 0;
}

View the result on Ideone

Note that I left uninitialized values in the array to simplify the code. In Ideone are appearing as zeros, but it is not guaranteed to be so, so it would be good practice to assign values throughout the array.

    
12.11.2017 / 20:38