2010-09-28 13 views
7

Sto prendendo una classe su C e si sta verificando un errore di segmentazione. Da quanto ho capito, si suppone che i guasti dei segmenti si verifichino quando si accede alla memoria che non è stata allocata, o comunque fuori dai limiti. Ovviamente tutto ciò che sto cercando di fare è inizializzare un array (anche se piuttosto grande)Seg Fault durante l'inizializzazione dell'array

Sto semplicemente fraintendendo come analizzare un array 2d? Misplacing un bound è esattamente ciò che causerebbe un errore di seg-- mi sbaglio nell'utilizzare un nidificato for-loop per questo?

Il professore ha fornito le funzioni dell'orologio, quindi spero che non sia questo il problema. Sto eseguendo questo codice in Cygwin, potrebbe essere questo il problema? Segue il codice sorgente. Usando anche lo standard C99.

Per essere perfettamente chiari: sto cercando aiuto per capire (e eventualmente risolvere) il motivo per cui il mio codice produce un errore di 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

Questa è una grande domanda per i compiti. Ben scritto, ben pensato e alcune risposte delle persone mi hanno effettivamente insegnato qualcosa che non sapevo (in particolare, impongono limiti alle dimensioni). Ti lodo per questo, OP. –

+0

Non correlato alla tua domanda, ma visto che questo è compito a casa: sembra che il tuo primo 'start = time();' è nel posto sbagliato, dovrebbe essere appena prima del ciclo for, altrimenti il ​​suo reset di ogni ciclo, non serve scopo – Necrolis

risposta

9

tuo programma funziona correttamente sul mio computer (x86-64/Linux) così ho il sospetto che si sta eseguendo in un sistema specifico, limite sulla dimensione dello stack di chiamate. Non so quanto stack si ottiene su Cygwin, ma il tuo array è di 4.000.000 di byte (con 32-bit int), che potrebbe facilmente essere troppo grande.

provare a spostare la dichiarazione di majorArray di main (metterlo a destra dopo le #include s) - allora sarà una variabile globale, che proviene da un pool di allocazione diversa che può essere molto più grande.

Tra l'altro, questo confronto è indietro:

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

Inoltre, per fare un test come questo si dovrebbe davvero ripetere il processo per molti formati di array diverse e forme.

+0

Oh, whoops. Grazie per quella presa! ^.^;; INOLTRE: Spostare majorArray fuori dalla funzione principale ha funzionato, grazie! –

0

Questo codice funziona correttamente per me sotto Linux e non riesco a vedere nulla di chiaramente sbagliato in proposito. Puoi provare a eseguirne il debug via gdb. Compilare in questo modo:

gcc -g -o testcode test.c 

e poi dire

gdb ./testcode 

e in gdb dire run

Se si blocca, dire where e gdb ti dice, dove si è verificato l'incidente. Quindi ora in quale riga si trova l'errore.

6

Si sta cercando di afferrare 1000 * 1000 * sizeof(int) byte nello stack. Questo è più che il tuo sistema operativo consente la crescita dello stack. Se su qualsiasi Unix - controlla lo ulimit -a per la dimensione massima dello stack del processo.

Come regola generale, allocare strutture grandi sullo heap con malloc(3). O utilizzare array statici - al di fuori dell'ambito di qualsiasi funzione.

In questo caso, è possibile sostituire la dichiarazione di majorArray con:

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

Questo essere compiti, 'malloc' potrebbe non essere consentito. – zwol

1

Il programma funziona perfettamente quando compilato da gcc, & eseguito in Linux, Cygwin potrebbe benissimo essere il tuo problema qui.

3

Impossibile trovare alcun errore nel codice, quindi l'ho compilato ed eseguito e ha funzionato come previsto.

Bisogna, tuttavia, un errore semantico nel codice:

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

dovrebbe essere:

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

Inoltre, la condizione alla fine dovrebbe essere cambiato nel suo opposto:

if(rowMajor<colMajor) 

Infine, per evitare il problema della dimensione dello stack specifico per os, altri menzionati, è necessario definire vostra matrice esterna 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

Grazie. Ho preso personalmente il problema con l'orologio di avvio e ora ho aggiornato l'OP per riflettere questo. –

0

Se viene eseguito correttamente altrove, si sta probabilmente cercando di afferrare più spazio di stack che il sistema operativo consente. Stai allocando 4 MB nello stack (1 mill interi), il che è troppo per allocare "in sicurezza" nello stack. malloc() e free() sono le tue migliori scommesse qui.

Problemi correlati