elmarti
elmarti

Reputation: 11

Problems when i try to dynamically allocate an array of strings in C

I'am trying to figure out what's wrong with my code.When compiling, no errors or warning, just a segmentation fault.

Can someone tell me what am i doing wrong??

#include "funciones.h"
#define FILAS 5 
#define COLUMNAS 3
#define VALOR 2

int main(void)
{
    int estado;
    int **matriz = NULL;

    estado = generar_matriz(FILAS,COLUMNAS, 2, matriz);

    if(estado == OK)
    {
        printf("matriz creada exitosamente \n");
    }
    else
    printf("error en el creado de la matriz \n");
        
return 0;
}

#ifndef FUNCIONES_H_
#define FUNCIONES_H_

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

#define ERROR -1
#define OK 0

int generar_matriz(int filas, int columnas, int valor, int** matriz);


#endif 

#include "funciones.h"

int generar_matriz(int filas, int columnas, int valor, int** matriz)
{
    int estado = OK,i,j;
    
    if(filas != 0 && columnas != 0)
    {
        matriz = (int**)malloc(sizeof(int*)*filas);
        
        if(matriz != NULL)
        {
            for(i = 0;i<filas;i++)
            {
                matriz[i] = (int*)malloc(sizeof(int)*columnas);
            
                if(matriz[i] == NULL)
                estado = ERROR;

                else
                {
                   for(j = 0;j<columnas;j++)
                    *(matriz[j]) = valor;
                }
            }   
        }
        else
        estado = ERROR;

    }
    else
    estado = ERROR;

    return estado;  
}

`

I think the logic is pretty clear. The first malloc call is to allocate an array of int pointers, and then i use a for function to ask for memory and fill each 4 bytes with the number that the function recived. I also would accept better code practices and tips. Thank you.

Upvotes: 0

Views: 68

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

You are not allocating an array of strings. You are trying to allocate arrays of integers.

The function generar_matriz declared like

int generar_matriz(int filas, int columnas, int valor, int** matriz);

accepts the pointer matriz declared in main by value

estado = generar_matriz(FILAS,COLUMNAS, 2, matriz);

that is the function deals with a copy of the value of the original pointer matriz. Changing the copy does not changes the original pointer. It stays unchanged.

If to preserve your approach to the function definition then you need to pass a pointer to the function by reference. It means that the function should be declared like

int generar_matriz(int filas, int columnas, int valor, int*** matriz);

and called like

estado = generar_matriz(FILAS,COLUMNAS, 2, &matriz);

Within the function there is one more problem in these for loops

        for(i = 0;i<filas;i++)
        {
            matriz[i] = (int*)malloc(sizeof(int)*columnas);
        
            if(matriz[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
                *(matriz[j]) = valor;
                ^^^^^^^^^^^^^^^^^^^^^ 
            }
        }   

Instead you need to write

        for(i = 0;i<filas;i++)
        {
            matriz[i] = (int*)malloc(sizeof(int)*columnas);
        
            if(matriz[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
               matriz[i][j] = valor;
            }
        }   

But more precisely if the last function parameter will have the type int *** as it is required then the loops will look like

        for(i = 0;i<filas;i++)
        {
            ( *matriz )[i] = (int*)malloc(sizeof(int)*columnas);
        
            if( ( *matriz )[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
                ( *matriz )[i][j] = valor;
            }
        }   

Correspondingly this statement

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

must be rewritten like

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

Of you may not change the function declaration then you should implement the function such a way that it will dynamically allocate a one-dimensional array you will need yourself to access elements of the array simulating a tw-dimensional array.

For example

int generar_matriz(int filas, int columnas, int valor, int** matriz)
{
    int estado = OK,i,j;
    
    if ( filas > 0 && columnas > 0 )
    {
        *matriz = malloc( sizeof( int ) * filas * columnas );
        
        if ( *matriz != NULL)
        {
            for ( i = 0;i < filas; i++ )
            {
                for ( j = 0; j < columnas; j++ )
                    ( *matriz )[columnas * i +j] = valor;
                }
            }   
        }
        else
        estado = ERROR;
    }
    else
    estado = ERROR;

    return estado;  
}

So in main the pointer matriz will be declared like

int *matriz;

and passed to the function like

estado = generar_matriz(FILAS,COLUMNAS, 2, &matriz);

Upvotes: 1

0___________
0___________

Reputation: 67476

It is definitely not the array of strings.

The error is here:

*(matriz[j]) = valor;

It should be:

 matriz[i][j] = valor;

Another problem you have here is that you use the local copy of matrix and the object passed by the called is not modified.

Remarks.

  1. do not cast the result of malloc. If the code does not compile you are using the wrong compiler (C++ one)
  2. Use objects instead of types in sizeof's.

Upvotes: 0

Related Questions