Me gustaría saber por qué tengo este comportamiento:

Este es el código que estoy usando:

matriz2= (float**) malloc (sizeof(float**));
    for (int m=0;m<36;m++)
{
    matriz2[m]=(float *) malloc(36*sizeof(float*));
}


for (int k=0;k<36;k++)
{
        for (int l=0;l<36;l++)
        {
            matriz2[k][l]=i;
            i++;
            printf("%f\n ",matriz2[k][l]);
        }
}   

He comprobado algunas cosas sobre la asignación de memoria que hace malloc.

El siguiente código funciona bien si en cambio matriz2 [m] = (float *) malloc (36 * sizeof (float *)); Pongo (float *) malloc (35 * sizeof (float *));

Pero eso no pasa si lo hago con 34.

También verifiqué que el siguiente código funciona, de hecho funciona para cambiar los 3 por 4, con 5 falla:

matriz2= (float**) malloc (sizeof(float**));
    for (int m=0;m<3;m++)
{
    matriz2[m]=(float *) malloc(sizeof(float*));
}


for (int k=0;k<3;k++)
{
        for (int l=0;l<3;l++)
        {
            matriz2[k][l]=i;
            i++;
            printf("%f\n ",matriz2[k][l]);
        }
}   

Aunque por lo que entiendo de malloc, no debería poder llenar la matriz y debería ocurrir una falla de segmentación.

¿Por qué puedo llenar la matriz de esta manera?

Gracias.

-1
user2638180 14 jul. 2017 a las 00:49

2 respuestas

La mejor respuesta

Su código

matriz2= (float**) malloc (sizeof(float**));
for (int m=0;m<36;m++) {
    matriz2[m]=(float *) malloc(36*sizeof(float*));
}

Reserva espacio para un solo puntero, pero asigna 36 punteros y, por lo tanto, excede los límites de la matriz y produce un comportamiento indefinido (bloqueo, salida "divertida", ...).

Por lo general, está mezclando la semántica de punteros a punteros a flotantes en su código (por ejemplo, matriz2= (float**) malloc (sizeof(float**)) debería ser matriz2= (float**) malloc (36*sizeof(float*))).

Empecemos por una única dimensión. Si asigna espacio para una secuencia de 36 valores flotantes, escribirá malloc(36 * sizeof(float)). El resultado de esto será un puntero al primer valor flotante de esta secuencia y, por lo tanto, el tipo de resultado es float * (Por cierto: a diferencia de C ++, en C no debe emitir el resultado de {{X2 }}). Tenga en cuenta que, para obtener una secuencia de valores flotantes, escribe 36 * sizeof(float), y no 36 * sizeof(float*), que sería una secuencia de punteros a flotantes. Por lo tanto, una sola dimensión se asigna de la siguiente manera:

float *row = malloc(36 * sizeof(float));

Si ahora tiene una secuencia de tales filas (cada una tiene el tipo float *), necesita asignar espacio para una secuencia de tales punteros, es decir, malloc (36 * sizeof(float*)), y el resultado es un puntero al primer puntero de esta secuencia de punteros. Por lo tanto, el tipo de resultado es float**:

float **matrix = malloc(36 * sizeof(float*))

Luego puede reservar espacio para cada fila y asignarlo:

float **matrix = malloc(36 * sizeof(float*))  // sequence of pointers to rows
for (int m=0;m<36;m++) {
    matrix[m]=malloc(36*sizeof(float));  // row, i.e. sequence of floats
}

Espero que ayude.

4
Stephan Lechner 13 jul. 2017 a las 22:13

Su malloc inicial es demasiado pequeño (35 veces :))

1
P__J__ 13 jul. 2017 a las 21:54