[RISOLTO] C++: inizializzare un *grosso* array

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

[RISOLTO] C++: inizializzare un *grosso* array

Messaggio da Spiros »

Devo immagazzinare in un array molti, molti numeri (almeno 100.000.000). Ma nel mio programma, quando lo inizializzo cosi": long unsigned int numeri[1000000]; (un milione) funziona; quando lo inizializzo cosi': long unsigned int numeri[10000000]; (10 milioni), non funziona: g++ lo compila senza problemi, ma il programma si blocca ed esce.

Non posso avere un array con milioni di valori?
Ultima modifica di Spiros il mercoledì 10 ottobre 2007, 17:15, modificato 1 volta in totale.
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
furetto76
Prode Principiante
Messaggi: 73
Iscrizione: sabato 1 settembre 2007, 15:42

Re: C++: inizializzare un *grosso* array

Messaggio da furetto76 »

dopo 10000000 metti una L (long) così 10000000L
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

Re: C++: inizializzare un *grosso* array

Messaggio da Spiros »

Come in python?
Aspetta, aggiungo un particolare: io non so a priori quanti elementi deve avere l'array, perche' questo numero e' preso dallo std::cin (va da se' che se il programma lo usiamo solo nel nostro gruppo di lavoro so che cosa metteremo nel std::cin, piu' o meno). Il codice e' cosi':

Codice: Seleziona tutto

long unsigned quanti;
std::cout << "Quanti numeri?" << std::endl;
std::cin >> quanti;
long unsigned numeri[quanti];
Quindi, come vedi, la variabile quanti e' gia' long. Credo che basti. Che cosa ne dite?
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
simo_magic
Rampante Reduce
Rampante Reduce
Messaggi: 9496
Iscrizione: lunedì 18 dicembre 2006, 21:37
Località: Piemonte

Re: C++: inizializzare un *grosso* array

Messaggio da simo_magic »

Eres ha scritto: Devo immagazzinare in un array molti, molti numeri (almeno 100.000.000). Ma nel mio programma, quando lo inizializzo cosi": long unsigned int numeri[1000000]; (un milione) funziona; quando lo inizializzo cosi': long unsigned int numeri[10000000]; (10 milioni), non funziona: g++ lo compila senza problemi, ma il programma si blocca ed esce.

Non posso avere un array con milioni di valori?
si ma devi ricordare che ogni pezzo del vettore occupa spazio in memoria che lo usi o che non lo usi...10^6  celle del vettore ognuna da un numero long sono 8 byte per elemento...sono circa 8 megabytes...prova a farne tu un vettore con 10^8...800MB di array!!!
Avatar utente
andyoso
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 720
Iscrizione: venerdì 20 luglio 2007, 1:17
Località: Napoli

Re: C++: inizializzare un *grosso* array

Messaggio da andyoso »

Aspetta, aggiungo un particolare: io non so a priori quanti elementi deve avere l'array, perche' questo numero e' preso dallo std::cin (va da se' che se il programma lo usiamo solo nel nostro gruppo di lavoro so che cosa metteremo nel std::cin, piu' o meno).
Scusa ma a questo punto non ti  conviene inizializzare in questo modo il programma?:
int n;
cout;
cin>>n;
int array[n];
In questo modo avrai un risparmio notevole della memoria perchè avrai un array su misura per te ogni volta che avvii il programma.


P.S. Scusa la domanda ma a cosa ti serve un array di  100.000.000 elementi??
Ultima modifica di andyoso il lunedì 8 ottobre 2007, 20:39, modificato 1 volta in totale.
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: inizializzare un *grosso* array

Messaggio da bite »

L'array viene allocato sullo stack.
Prova a dare

Codice: Seleziona tutto

ulimit -s
A me risponde 8192 (kB), cioé 8192*1024=8388608 bytes. Anche a te?
Tu chiedi un array di 10000000 o 100000000 di unsigned long, cioé 40000000 ovvero 400000000 di bytes. Non ci sta.
Prova a dare

Codice: Seleziona tutto

ulimit -s unlimited
oppure ad allocare l'array nello heap (new se usi c++, malloc se usi c).
Poi ricorda di fare, rispettivamente, delete[] o free.
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: inizializzare un *grosso* array

Messaggio da bite »

Nota: int, unsigned int, long, unsigned long sono sempre 4 bytes. 8 bytes sono i long long.
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

Re: C++: inizializzare un *grosso* array

Messaggio da Spiros »

Già, dev'essere la memoria che non va. Allora mi consigliate una lettura per capire veramente la differenza tra stack e heap (oppure me lo spiegate direttamente)? Comunque, io il programma lo provo a casa mia, su un computer un po' cessetto, ma poi in realtà lo faremo girare sul computer del politecnico che dovrebbe avere diversi GB di RAM.
Comunque, come faccio a inizializzarlo sullo heap? Se ho capito bene long unsigned numeri = new array(n.elementi)?
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: inizializzare un *grosso* array

Messaggio da bite »

Eres ha scritto: Già, dev'essere la memoria che non va. Allora mi consigliate una lettura per capire veramente la differenza tra stack e heap (oppure me lo spiegate direttamente)? Comunque, io il programma lo provo a casa mia, su un computer un po' cessetto, ma poi in realtà lo faremo girare sul computer del politecnico che dovrebbe avere diversi GB di RAM.
Comunque, come faccio a inizializzarlo sullo heap? Se ho capito bene long unsigned numeri = new array(n.elementi)?

Codice: Seleziona tutto

unsigned int * numeri = new unsigned int [numero_elementi];
...
numeri[i] = ...;
...
delete[] numeri;
Prevedo tra un po', se proseguirai, una lamentela sulla lentezza dei calcoli. Posta qui che ti parlerò della funzione mlockall.  (rotfl)

Per quanto riguarda stack e heap: non c'è differenza fisica, per farla molto breve:
- quando dichiari una variabile (anche un array grossissimo) dentro a uno "scope" (main, funzione, ciclo for etc etc: tutto ciò che sta tra parentesi graffe) tale variabile va a finire sullo stack e viene rilasciata quando esci dallo scope (non se entri in uno scope annidato)
- se invece usi new o malloc la variabile va a finire sullo heap, dove sopravvive allo scope e muore solo quando chiami esplicitamente delete o free.
- la gestione di stack e heap è separata e ci sono tradizionalmente dei limiti diversi.

Questa spiegazione super-banalizzante non ti esime dal dovere di informarti meglio.
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

Re: C++: inizializzare un *grosso* array

Messaggio da Spiros »

Ok, ci proverò.

Un mio amico mi ha detto che le variabili in un corso che ha fatto le inizializzavano fuori scope, subito dopo gli #include. A quel punto vanno sull'heap o sullo stack?
Comunque io non lo farò e farò come dici tu. Non ti ho detto, intanto, che io uso C++.
Ultima modifica di Spiros il martedì 9 ottobre 2007, 16:31, modificato 1 volta in totale.
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
sanjelanka
Prode Principiante
Messaggi: 218
Iscrizione: sabato 18 febbraio 2006, 20:05

Re: C++: inizializzare un *grosso* array

Messaggio da sanjelanka »

comunque se non ricordo male
se fai un allocazione statica le variabili del vettore vengono messi tutti in fila nella memoria ...
chiundi se non hai lo spazio giusto a volte hai dei problemi...
per un numero elevato di elementi di solito si usa una struttura lista (però ha una scansione più lenta perchè è un gioco di puntatori in quanto ogni elemento viene allocato in un posto diverso nella ram , ritrovandoti con un vettore con gli elementi sparsi quà e la..  (rotfl) )...

ma in questo caso gli elementi sono tutti int ...
Ultima modifica di sanjelanka il martedì 9 ottobre 2007, 16:22, modificato 1 volta in totale.
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: inizializzare un *grosso* array

Messaggio da bite »

Eres ha scritto: Ok, ci proverò.

Un mio amico mi ha detto che le variabili in un corso che ha fatto le inizializzavano fuori scope, subito dopo gli #include. A quel punto vanno sull'heap o sullo stack?
Ancora in un terzo posto (variabili globali).
Comunque io non lo farò e farò come dici tu. Non ti ho detto, intanto, che io uso C++.
Scrivi questo programmino di poche righe:

Codice: Seleziona tutto

const int dim = 100000000;
unsigned int pippo [dim];
int main () {
  pippo[dim - 1] = 1;
  return 0;
}
Compilalo con:

Codice: Seleziona tutto

g++ -save-temps numeri.cpp
Apri in un editor il file numeri.s:

Codice: Seleziona tutto

	.file	"numeri.cpp"
	.text
	.align 2
.globl main
	.type	main, @function
main:
.LFB2:
	leal	4(%esp), %ecx
.LCFI0:
	andl	$-16, %esp
	pushl	-4(%ecx)
.LCFI1:
	pushl	%ebp
.LCFI2:
	movl	%esp, %ebp
.LCFI3:
	pushl	%ecx
.LCFI4:
	movl	$1, pippo+399999996
	movl	$0, %eax
	popl	%ecx
	popl	%ebp
	leal	-4(%ecx), %esp
	ret
.LFE2:
	.size	main, .-main
.globl __gxx_personality_v0
.globl pippo
	.bss
	.align 32
	.type	pippo, @object
	.size	pippo, 400000000
pippo:
	.zero	400000000
	.ident	"GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
	.section	.note.GNU-stack,"",@progbits
Prova a immaginare che cosa vogliono dire le istruzioni assembler.
Modifica il programma originale aggiungendo qualcosa sullo stack, poi qualcosa sullo heap, e guarda come si riflettono le modifiche nel .s
Si imparano tante cose.

Ciao, buon divertimento
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

Re: C++: inizializzare un *grosso* array

Messaggio da Spiros »

bite ha scritto: Prevedo tra un po', se proseguirai, una lamentela sulla lentezza dei calcoli. Posta qui che ti parlerò della funzione mlockall.  (rotfl)
Mi pare proprio di no, anzi, il programma è velocissimo. Non dovrebbe?

Provero` anche g++ -save-temps numeri.cpp. Non ho mai messo il naso in assembly. Forse è giunto il momento...  8)

Grazie mille.
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: inizializzare un *grosso* array

Messaggio da bite »

Eres ha scritto:
bite ha scritto: Prevedo tra un po', se proseguirai, una lamentela sulla lentezza dei calcoli. Posta qui che ti parlerò della funzione mlockall.  (rotfl)
Mi pare proprio di no, anzi, il programma è velocissimo. Non dovrebbe?
Se l'array viene swappato (va a finire su disco) potrebbero esserci dei rallentamenti. Se non ne vedi, non preoccupartene.
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

C++: Leggere e scrivere su file

Messaggio da Spiros »

Risolto questo problema, il successivo è aprire un file in lettura, leggerlo; aprirlo in scrittura, modificarlo.
Dove trovo info?  ;D
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: C++: Leggere e scrivere su file

Messaggio da bite »

Eres ha scritto: Risolto questo problema, il successivo è aprire un file in lettura, leggerlo; aprirlo in scrittura, modificarlo.
Dove trovo info?  ;D
Queste sono facili da trovare.  ;D ;D
Avatar utente
Spiros
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1100
Iscrizione: martedì 21 marzo 2006, 15:11
Località: Zurigo

Re: C++: inizializzare un *grosso* array

Messaggio da Spiros »

Va bene, mi arrangero'  ;)

Scrivo [RISOLTO] e considero chiuso.  (z)  (good)

Grazie a tutti.
Spiros
HP Compaq 6910p - Intel Core2 Duo T7500 @ 2.20GHz - 2GB DDR2 - HD 120GB - ATI Mobility Radeon X2300 - Intel PRO/Wireless 4965 AG
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti