2010-09-28 10 views
7

Estoy tomando una clase en C y me encuentro con un error de segmentación. Por lo que entiendo, se supone que las fallas seg ocurren cuando estás accediendo a la memoria que no ha sido asignada, o de otra manera fuera de los límites. "Por supuesto, todo lo que estoy tratando de hacer es inicializar una matriz (aunque bastante grande)Error de Seg al inicializar la matriz

¿Simplemente estoy malentendiendo cómo analizar una matriz 2d? La colocación errónea de un límite es exactamente lo que causaría un fallo seg. ¿Me equivoco al usar un for-loop anidado para esto?

El profesor proporcionó las funciones del reloj, así que espero que ese no sea el problema. Estoy ejecutando este código en Cygwin, ¿podría ser ese el problema? El código fuente sigue Usando el estándar c99 también.

Para ser perfectamente claro: estoy buscando ayuda para entender (y finalmente arreglar) el motivo por el cual mi código produce un fallo seg.

#include <stdio.h> 
#include <time.h> 
int main(void){ 
    //first define the array and two doubles to count elapsed seconds. 
    double rowMajor, colMajor; 
    rowMajor = colMajor = 0; 
    int majorArray [1000][1000] = {}; 

    clock_t start, end; 

    //set it up to perform the test 100 times. 
    for(int k = 0; k<10; k++) 
    { 
    start=clock(); 
    //first we do row major 
    for(int i = 0; i < 1000; i++) 
    { 
     for(int j = 0; j<1000; j++) 
     { 
      majorArray[i][j] = 314; 
     } 
    } 
    end=clock(); 
    rowMajor+= (end-start)/(double)CLOCKS_PER_SEC; 
    //at this point, we've only done rowMajor, so elapsed = rowMajor 
    start=clock(); 
    //now we do column major 
    for(int i = 0; i < 1000; i++) 
    { 
     for(int j = 0; j<1000; j++) 
     { 
      majorArray[j][i] = 314; 
     } 
    } 
    end=clock(); 
    colMajor += (end-start)/(double)CLOCKS_PER_SEC; 
    } 
    //now that we've done the calculations 100 times, we can compare the values. 
    printf("Row major took %f seconds\n", rowMajor); 
    printf("Column major took %f seconds\n", colMajor); 
    if(rowMajor<colMajor) 
    { 
    printf("Row major is faster\n"); 
    } 
    else 
    { 
     printf("Column major is faster\n"); 
    } 

    return 0; 

} 
+1

Esta es una gran pregunta para la tarea. Bien escrito, bien pensado, y las respuestas de algunas personas en realidad me enseñaron algo que no sabía (específicamente límites de tamaño de la pila). Te felicito por esto, OP. –

+0

No relacionado con tu pregunta, pero viendo que es tarea: parece que tu primer 'start = time();' está en el lugar equivocado, debería estar justo antes del ciclo for, de lo contrario, se restablecería cada ciclo, sin servicio propósito – Necrolis

Respuesta

9

que el programa funciona correctamente en el equipo (x86-64/Linux) así que sospecho que se está ejecutando en un determinado sistema de límite en el tamaño de la pila de llamadas. No sé cuánta pila obtendrás en Cygwin, pero tu matriz es de 4.000.000 de bytes (con 32 bits int), eso podría ser demasiado grande.

trate de mover la declaración de majorArray de main (ponerlo justo después de los #include s) - entonces será una variable global, que viene de una piscina asignación diferente que puede ser mucho más grande.

Por cierto, esta comparación es al revés:

if(rowMajor>colMajor) 
{ 
    printf("Row major is faster\n"); 
} 
else 
{ 
    printf("Column major is faster\n"); 
} 

Además, para hacer una prueba como esta que realmente debería repetir el proceso para muchos diferentes tamaños y formas de matriz.

+0

Oh, gracias. Gracias por esa atrapada! ^.^;; TAMBIÉN: Moviendo majorArray fuera de la función principal hizo el truco, ¡gracias! –

0

Este código funciona bien para mí en Linux y no puedo ver nada obvio al respecto. Puede intentar depurarlo a través de gdb. Compilar así:

gcc -g -o testcode test.c 

y luego decir

gdb ./testcode 

y en GDB decir run

Si se bloquea, por ejemplo where y GDB le dice, donde ocurrió el accidente. Entonces ahora en qué línea está el error.

6

Usted está tratando de agarrar 1000 * 1000 * sizeof(int) bytes en la pila. Esto es más que su sistema operativo permite el crecimiento de la pila. Si está en cualquier Unix, verifique ulimit -a para conocer el tamaño máximo de la pila del proceso.

Como regla general, asigne grandes estructuras en el montón con malloc(3). O use arrays estáticos, fuera del alcance de cualquier función.

En este caso, puede sustituir a la declaración de majorArray con:

int (*majorArray)[1000] = calloc(1000, sizeof majorArray); 
+0

Siendo esta tarea, 'malloc' puede no estar permitido. – zwol

1

El programa está funcionando perfectamente cuando compilado por gcc, & ejecutado en Linux, Cygwin puede ser su problema aquí.

3

No pude encontrar ningún error en su código, así que lo compilé y lo ejecuté y funcionó como se esperaba.

Usted tiene, sin embargo, un error semántico en el código:

start=clock(); 
    //set it up to perform the test 100 times. 
    for(int k = 0; k<10; k++) 
    { 

debe ser:

//set it up to perform the test 100 times. 
    for(int k = 0; k<10; k++) 
    { 
    start=clock(); 

Además, la condición al final se debe cambiar a su inversa:

if(rowMajor<colMajor) 

Finalmente, para evitar el problema del tamaño de la pila específica del os que otros mencionaron, debe definir su matriz fuera de main():

#include <stdio.h> 
#include <time.h> 

int majorArray [1000][1000]; 

int main(void){ 
    //first define the array and two doubles to count elapsed seconds. 
    double rowMajor, colMajor; 
    rowMajor = colMajor = 0; 
+0

Gracias. Cogí el problema con el reloj de inicio yo mismo, y ahora he actualizado el OP para reflejar eso. –

0

Si funciona correctamente en otro lugar, lo más probable tratando de agarrar más espacio de pila que permite el sistema operativo. Está asignando 4MB en la pila (1 mill enteros), que es demasiado para asignar "de manera segura" en la pila. malloc() y free() son tus mejores apuestas aquí.

Cuestiones relacionadas