Duda matrices C

perez_chuck

Buenas,

ahora tengo otro problema. Se trata de una matriz dinámica en tiempo de ejecución. He buscado por internet y parece correcto, pero cuando intento guardar el 1º elemento se produce violación del segmento.

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

int main(){
    int fil, col;
	printf("Introduce el nº de filas: ");
	scanf("%d",&fil);
	printf("Introduce el nº de columnas: ");
	scanf("%d",&col);
	
int **m;
creaM(fil,col,m);

leeMatriz(fil,col,m);
}

void leeMatriz(int fil, int col, int **matriz){
	int i,j;
	for(i=0;i<fil;i++){
		for(j=0;j<col;j++){
			printf("\nIntroduce el valor [%d][%d]: ",i,j);
			scanf("%d", &matriz[i][j]);
		}
	}
}

void creaM(int filas, int columnas, int **matriz){
	matriz=(int **)malloc(filas*sizeof(int *));
    int i;
    for(i=0; i<filas;i++){
               matriz[i]=(int*)malloc(columnas*sizeof(int));
    }
}

Gracias!

r2d2rigo

en vez de int matriz[][] pasaselo como doble puntero (int **matriz), que es menos chungo.

1 respuesta
perez_chuck

#2 Ya la probé, pero cuando termina la primera fila y pasa a la 2º da error de segmentación, supongo que porque accede a una zona de memoria no permitida o algo así.

int main(){
	int fil=3;
	int col=4;
	int matriz[fil][col];
	int matriz2[fil][col];
	leeMatriz(fil,col,matriz);
	//writeMatriz (fil,col,matriz);

//system("PAUSE");
return 0;
}

void leeMatriz(int FIL, int COL, int **matriz){
	int i,j;
	for(i=0;i<FIL;i++){
		for(j=0;j<COL;j++){
			printf("\nIntroduce el valor [%d][%d]: ",i,j);
			scanf("%d", &matriz[i][j]);
		}
	}
}
1 respuesta
elkaoD

#3 esto es dar un tiro al aire, porque hace mucho que no toco C++, pero si no recuerdo mal las matrices en C++ en memoria quedar linearizadas por filas.

El doble puntero sólo se puede usar cuando has tirado de malloc (new) para definirlas, sin embargo si las has definido por código (que tu compilador lo ha hecho, supongo, aunque sean "variables" el tamaño) tienes que acceder a ellas con un puntero a secas.

O a lo mejor no, pero es lo que se me ha venido a la cabeza, porque a primera visto tu código está perfecto.

2 respuestas
DaRk-eXe

que recuerde.. las matrices se pasaban siempre por referencia no??

de todas formas en tu código,leeMatriz(fil,col,matriz); pasas matriz por valor y en la declaración de la función esperas un doble puntero de un entero.. algo falla ahí.

1 respuesta
elkaoD

#5 sí, si es por referencia igual, pero por referencia simple. En C++ si defines una matriz a capón no es un array de punteros a filas sino que quedan linearizadas en memoria directamente (no es como si hicieras un malloc del array y luego malloc para cada fila.)

No está pasando la matriz por valor. Un array por definición es un puntero.

perez_chuck

#4 Es C, ni C++ ni C#. En C++ la matriz se puede declarar como en JAVA creo.
Si solo pongo un * da error en la línea 18:
error: el valor del subíndice no es ni matriz ni puntero ni vector

1 respuesta
elkaoD

#7 humm vale, me confundió la definición de la matriz. Pues... ni idea, el código parece correcto (aunque me espiga que tu compilador acepte variables en la definición de la matriz.)

B

void leeMatriz(int FIL, int COL, int *matriz){
}

leeMatriz(fil,col, &matriz[0][0]);

Lo puedes hacer así. Es decir, pasas la dirección donde comienza tu array, y como le pasas las dimensiones también pues ya está hecho.

Intenta mejorar el estilo de tu código, las variables siempre en minúsculas, y si quieres que FIL y COL sean constantes tendrán que ser arriba en un #define o en el main en mayusculas, no en la función.

Mayusculas = constantes, minúsculas variables. y las funciones se suelen poner en minúsculas con _, es decir, lee_matriz, por ejemplo.

1 respuesta
LOc0

#1 Necesitas pasarle el número de columnas para que al hacer el direccionamiento sepa dónde colocarse. NO es lo mismo decir dame el elemento [5][100] de una matriz [10][1000] (51000 + 100 = 5100) que de una [10][200] (5200 + 100 = 1100). (Lo que dice #4)

Salu2 ;)

1 1 respuesta
perez_chuck

#9 Da el mismo error que en # 7
Este es el estilo de JAVA, me costará adaptarme al principio xD

B
#include <stdio.h>

void leeMatriz(int FIL, int COL, int (*matriz)[3]){
        int i,j;
        for(i=0;i<FIL;i++){
                for(j=0;j<COL;j++){
                        scanf("%d", &matriz[i][j]);
                }
        }
}

int main(){
        int array[4][3];

    leeMatriz(4, 3, array);
    return 0;
}

Arreglalo tú, que estoy en el curro. Si te surge duda dime.

perez_chuck

#10 Algo así leí, pero se me hace muy raro. Igual al principio cuando lo desarrollaron lo hacían así, pero me parece extraño que no implementaran posteriormente algo como esto:

void leeMatriz(int matriz[][])

int matriz[3][4];
leeMatriz(matriz);

Así cuando reconoce automáticamente el tamaño.

Se puede usar una constante en vez del valor directamente?

1 respuesta
LOc0

#13 C es un "ensamblador-bonito-muy-optimizado" ;) FIN

Salu2 ;)

PD:

#include <stdio.h>


void matrix(int f, int c, int TOT_COL, int *m)
{
	printf("%d", *(m + TOT_COL*f+c)); 
}


int main()
{
	int m[10][20];
	
m[5][10]=7;

matrix(5, 10, 20, (int*)m);//Imprime m[5][10]

return 0;
}
 
2
11 días después
perez_chuck

Buenas de nuevo, ahora el problema lo tengo con una matriz dinámica en tiempo de ejecución, a ver si me podéis echar una mano.

En 1 está el código.

2 respuestas
elkaoD

#15 abre otro hilo (y deja el contenido original.)

Puede ser útil para futura referencia/peña que venga de Google, etc.

Ya tarde, pero para la próxima.

angelorz

#15 prueba con CALLOC.


void creaM(int filas, int columnas, int **matriz){
    matriz=(int **)calloc(filas,sizeof(int *));
    int i;
    for(i=0; i<filas;i++){
               matriz[i]=(int*)calloc(columnas,sizeof(int));
    }
}

Otra manera sería pasando &m, siendo m char*, creo, en lugar de m como char**

1 respuesta
perez_chuck

#17 Esa manera como la mía, produce el fallo cuando intento insertar el 4º elemento, es decir, el 1º elemento de la 2º fila.

Introduce el nº de filas: 3
Introduce el nº de columnas: 3

Introduce el valor [0][0]: 1

Introduce el valor [0][1]: 1

Introduce el valor [0][2]: 1

Introduce el valor [1][0]: 1


Program has been terminated receiving signal 11 (Segmentation fault)

1 respuesta
elkaoD

#18 en creaM estás asignando el resultado de malloc al argumento, no a la variable pasada por referencia.

Solución:

*matriz = (int**)malloc(filas * sizeof(int*));
1 respuesta
LOc0

Truqui del almendruqui:

Cuando quieras reservar memoria dentro de una función, el puntero que le envíes tiene que ser de un "grado" más. Ejemplo:

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

void reserva_array(int **a, int n)
{
   *a=(int*)malloc(n*sizeof(int));
}

void reserva_matriz(int ***a, int f, int c)
{
   int i;
   
*a=(int**)malloc(f*sizeof(int*)); for(i=0; i<f; i++) (*a)[i]=(int*)malloc(c*sizeof(int)); } int main() { int *a, **b; reserva_array(&a, 5); a[4]=7; printf("%d\n", a[4]); reserva_matriz(&b, 5, 5); b[4][4]=8; printf("%d\n", b[4][4]); return 0; }

Esto es necesario en C porque TODO se pasa por VALOR incluído los punteros. Por lo que si le pasas a la función el puntero "tal cual", lo que recibirá será una copia de ese puntero y todo lo que haga con esa variable (como asignarle la dirección de un malloc) se perderá al salir de la función.

Salu2 ;)

1 respuesta
elkaoD

EDIT: No he dicho nada :rolleyes:

perez_chuck

#19 #20 Gracias!

Usuarios habituales