Newsgroup: it.comp.lang.c++
Titolo: dimensione array

int main()
{
    int a[1000000];
}
Questo me lo compila correttamente senza errori
Appena lo eseguo, pero', mi da degli errori di accesso alla memoria.
Suppongo che sia un problema di dimensioni troppo grandi dell'array...
giusto?
come lo risolvo?
--
Gerolamo

 come lo risolvo?
devi usare array dinamici altrimenti allochi nello stack e purtroppo è
limitato
int *c;
c = new int[100000];
poi alla fine quando non ne hai più bisogno deallochi
delete c;
ciao

 come lo risolvo?
array dinamici con new :))
ciao

 writes:

E perche'?  Io suggerirei invece di procurarsi un
compilatore/linker/ambiente di sviluppo che non sia
bacato.  Provare per credere:
MLO@mlinux 5 $ cat foo.cxx
#include <iostream>
int main() {
  int a[1000000];
  for (int i = 0;   i < 1000000;   ++i) a[i] = i;
  std::cout << "a[42] = " << a[42] << std::endl;
  return 0;
}
MLO@mlinux 6 $ g++ -ansi -Wall -o foo foo.cxx && ./foo
a[42] = 42
MLO@mlinux 7 $
Non vedo perche' un array sullo heap dovrebbe essere diverso
da un array sullo stack.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

 bacato.  Provare per credere:
Che c'entra un ambiente di sviluppo con le 'limitazioni' di un dato
OS ?
--
Bye,
  Mirko


non è detto sia bacato il compilatore..
le dimensioni dello stack possono dipendere da tante cose ..
ciao

Suppongo che sia un problema di dimensioni troppo grandi dell'array...
no, troppo piccolo lo stack :)
ogni variabile locale viene allocata sullo stack o, meglio, ad ogni
variabile locale viene assegnato spazio sullo stack.
supponendo che tu conosca l'oggetto stack, questo ha una dimensione
massima che non puoi superare (di solito 1 mega).
in realta' potresti modificare la dimensione massima dello stack
in fase di compilazione, riuscendo a compilare e a far girare perfettamente
il tuo codice. 
Il fatto che sia meglio utilizzare memoria "dinamica" piuttosto che memoria
statica (meglio, su stack) non dipende a mio avviso da quanta memoria ti serve,
bensi' dal problema che stai cercando di risolvere: in altre parole dipende
se conosci a priori i limiti del tuo problema.
hope to be clear (non lo shampoo :p)
saluti,
Francesco Picasso
http://francesco.netsigners.com


non e' piu' corretto "delete[] c"  ?
-- 
  _  _  >>Now at work<<  _     || ICQ number.................Non lo uso
 | \| |___ _____ ___ ___|_|___ || Home-Page ................Non ce l'ho
 | .` | -_|     | -_|_ -| |_ -||| E-Mail................Non l'avrai mai
 |_|\_|___|_|_|_|___|___|_|___||| Un Nemesis che ha pochi e-contatti ;)

> non e' piu' corretto "delete[] c"  ?
non è "solo più corretto" ma è quello da usare :))
giusta la precisazione ...
sorry mio errore

 le dimensioni dello stack possono dipendere da tante cose ..
Le "dimensioni dello stack" sono un nonsenso.  Gradirei che definissi
in maniera coerente questo concetto.
Se parliamo di C++ standard (ne dubito visto l'ignoranza che hai
mostrato, assieme alla tua strafottenza, in altri messaggi): ebbene,
il C++ definisce gli arrays in ISO/IEC 14882:1998 8.3.4; e l'operatore
'sizeof' in (ibid.) 5.3.3 --- in particolare il tipo restituito,
size_t, e' in 5.3.3.6 .
A norma di definizione, le dimensioni di un array devono poter essere
rappresentate usando un tipo denominato size_t, che e' definito in
modo implementation-dependent nell'header standard <cstddef>.  Se una
implementazione definisce un size_t in grado di rappresentare il
numero "1000000" (un milione) e non permette di definire un array di
un milione di elementi, ebbene quella implementazione e' errata a
norma di Standard e non e' C++.


 massima che non puoi superare (di solito 1 mega).
[OT]
Nessuno ha mai sentito parlare di "memoria virtuale"?  Perche' uno
stack devrebbe essere limitato a un mega (suppongo di bytes di 8
bits)?
Magari c'e' ancora chi conta ancora sulle dita, e pensa che gli interi
siano limitati a 10...  almeno io (che so contare sulle dita in binario
[*]) arrivo a 1023.
[*] Esercitatevi; e' ottimo per impressionare gli amici.  Ho provato
    anche in ternario, dito chiuso/flesso/disteso, per arrivare a
    59048; ma e' troppo difficile.


 non e' piu' corretto "delete[] c"  ?
Anzi, e' l'*unica* forma corretta.
Ciao,
Nicola

 mostrato, assieme alla tua strafottenza, in altri messaggi): ebbene,
alle persone maleducate non rispondo
plonk

     59048; ma e' troppo difficile.
io uso il binary clock di Gnome, e' lo stesso?

 wrote in message
news:RvZA7.74809$1H1.7...@news.infostrada.it...

Troppa roba sulla stack. O allochi dinamicamente o usi memoria globale.
Ovvero:
int main()
{
    int *a=new int[1000000];
    // ...
    delete [] a;
}
opppure
int a[1000000];
int main()
{
}
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 wrote in message
news:KFZA7.74923$1H1.7...@news.infostrada.it...

No. Devi usare delete [] c;


 No. Devi usare delete [] c;
scusa ma non leggi gli altri post ???
diciamo che non li hai letti :))
ciao

 da un array sullo stack.
Non lo è in se. Ma Widows come sistema operativo quando carica
l'eseguibile alloca spazio per le variabili globali e per lo stack in
base a quanto sta scritto nell'eseguibile. Lo spazio globale non cambia.
Lo stack e l'heap si. L'heap non è allocato dal sistema operativo ma dal
codice di libreria del programma. Lo stack invece è gestito dal sistema
operativo. Lo stack cresce on demand ma il meccanismo si basa sul
rilevamento di accessi negli ultimi Kb dello spazio attualmente allocato
(credo 4K). Sarebbe possibile scrivere un compilatore che che si
comporta correttamente (per questo ho scritto "probabilmente darebbe
problemi") ma la stragrande maggioranza dei compilatori per windows "per
defualt" non fanno verifiche sulla crescita dello stack.
Nota: gli aficionados di linux diranno che è un'altra cavolata di
windows. In realtà la cosa è documentata e un OS ha tutti il diritto di
comportarsi in questo modo anche se il modello di memoria risultante non
è lo stesso del C/C++. Una piattaforma C/C++ deve conoscere e tenere
conto del tipo di gestione della memoria (incluso lo stack) del sistema
operativo sottostante e non viceversa. L'OS prevede più di un meccanismo
per gestire il problema, il resto sta al compilatore (come giustamente
dici tu). Però è un fatto che la maggior parte dei compilatori non lo
fanno.


 norma di Standard e non e' C++.
Che le dimensioni debbano essere esprimibili in size_t č vero. Ma che la
memoria globale o lo stack o l'heap debbano permettere l'istanziazione
di qualunque numero di oggetti di qualunque dimensione esprimibile con
size_t non č vero.
Una implementazione puň benissimo definire un limite (anche runtime)
alla memoria utilizzata. E questo vale anche per la dimensione dello
stack.
Ma il problema č un'altro: non la dimensione dello stack ma un limite di
crescita nelle dimensioni dello stack un unica soluzione.
In ogni caso l'implementazione, piů che essere errata a norma di
standard, č errata perchč non tiene conto di come funziona l'OS. Perň č
un fatto che lo sono quasi tutte.


 bits)?
Perchč a seconda di come č fatto l'OS potrebbe essere effettivamente
limitato. In Windows esistono due modelli per lo stack: dimensione fissa
predefinita e dimensione variabile. Se compili un programma con stack a
dimensione fissa ovviamente non puoi superare quella dimensione. Se
compili con dimensione variabile, l'OS ti da almeno due diversi metodi
per cambiare quella dimensione, uno dei quali č automatico purchč siano
sosddisfatte alcune condizioni.
Se il compilatore crea un eseguibile con stack a dimensione fissa oppure
ne crea uno con stack a dimensione variabile ma non varia a rutime la
dimensione ne soddisfa le condizioni perchč vari automaticamente, ovvio
che l'OS si incazzi.
La maggior parte dei compilatori windows sono fatti cosě. E' un fatto.


darebbe problemi. Dico probabilmente perchè non l'ho mai provato.
Con cygwin va
demian@DEMIAN ~
$ cat foo.cxx
#include <iostream>
int main() {
  int a[1000000];
  for (int i = 0;   i < 1000000;   ++i) a[i] = i;
  std::cout << "a[42] = " << a[42] << std::endl;
  return 0;
}
demian@DEMIAN ~
$ g++ -ansi -Wall -o foo foo.cxx && ./foo
a[42] = 42
demian@DEMIAN ~
$
-- 
Marco Barisione (ICQ 84277092)

 un fatto che lo sono quasi tutte.
cmq indipendentemente dal sistema o da qualsiasi standard allocare array
statici nel main di quelle dimensioni è una cosa folle sotto qualsiasi
principio.Mi sembra superfluo parlare di queste soprattutto tra persone come
voi dotati di una certa esperienza.
ciao

delete c;
Quindi era sbagliato.
Il Ghenio
-----
These are my parting words to you:
those who give up are doomed!
-----


sbagliato cosa???
specifica l'errore

 Con cygwin va
Ok. Infatti avevo detto "probabilmente". Non è affatto impossibile fare
un compilatore che funzioni come ci si aspetta. Solo che la maggior
parte dei compilatori (tranne forse le ultime versioni) non gestivano il
discorso dello stack. O meglio: non per default. I compilatori MS per
esempio mi pare che richiedessero degli switch apposta.


 wrote in message
news:A6dB7.79556$1H1.8...@news.infostrada.it...

Mica vero. Ci sono sistemi in cui tutte le allocazioni dinamiche devono
essere liberate prima della fine della funzione che le alloca e non
esiste un heap.
Non sto parlando di sistemi operativi o di linguaggi. Sto parlando di
sistemi SW (soprattutto in ambito militare o aerospaziale) in cui questo
requirement fa parte delle specifiche.
Non c'è nessun motivo per cui lo stack non debba essere usato per
quantità massive di dati. Salvo che il sistema operativo o l'HW non ne
limitino la dimensione a priori.


guarda che per quanto riguarda il delete C ho specificato che era una
dimenticanza ma se poi vuoi credere quello che vuoi sei libero di farlo

 diciamo che non li hai letti :))
Diciamo che li ho letti dopo aver postato.



no aspetta stiamo parlando di sistemi con stak ed heap...
non allarghiamo il discorso ad applicazioni particolari altrimenti "facciamo
notte".Visto che questo discorso č stato comincianto date le esatte
informazione.
Lo stack va usato ocn molta parsimonia e soprattutto non bisogna allocare
array enormi nel main in quanto vengono rilasciati solo alla fine del
programma.
ciao

 programma.
Sei proprio sicuro che il gestore della memoria dinamica del compilatore
che usi restituisca la memoria al sistema *prima* che il programma
termini? Non e' cosi' scontato...
Ciao,
Nicola

 programma.
Se l'array serve per tutto il tempo che sia allocato nell'heap, globale
o nello stack cosa cambia?


 termini? Non e' cosi' scontato...
nicola allora dovremmo parlare anche della deframmentazione della memoria ??
non credo che si possa includere proprio tutto.Si danno le informazioni più
utili :))

 come lo risolvo?
#include <vector>
int main()
{
        std::vector a(1000000);
}
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

bits)?
nel mio post ho citato chiaramente la possibilita' di impostare
una dimensione stack diversa da quella di default...
[OT]
utilizzare stack variabili non e', a mio avviso, una buon metodo di
programmazione, ma questo e' un altro discorso.
Francesco Picasso
http://francesco.netsigners.com

 --
ti dico il mio pensiero solo su questo che riguarda un discorso generale.
Supponi di avere array statici in funzioni ricorsive l'usare lo stack pensi
sia una buona idea??
Per quando riguarda il main se usi troppo spazio nello stack in "possibili"
funzioni ricorsive potresti non averne più a sufficienza.Poi ricorod ancor i
primi tempi (gli anni non te li dico so troppi) ritrovarmi errori di stack e
non sapere da dove incominciare.Sicuramente mi dirai che potrebbe esserci
gestioni più professionali, ma non dimentichiamoci che la magggior parte
delle persona non sa neppure che certi array vengono allocati nello stack
:))
ciao

 non sapere da dove incominciare.
Non so tu. Ma per me sono una quindicina di anni. E errori di stack
overflow ne ho visti tanti. Ma tutti dovuti o a ricorsione infinita
oppure a limitazioni del sistema operativo che non gestiva stack
dinamici.


darebbe problemi. Dico probabilmente perchè non l'ho mai provato.
No, funziona anche sotto windows (con cygwin), almeno per allocazioni
inferiori a circa 8e6. (Mi dicono che dipende dal fatto che "il gcc
usa, anche su win32, il proprio runtime stile unix, e quindi si puo'
permettere di usare uno stack enorme, perche' considera stack tutto lo
spazio di indirizzamento del processo".)
Per curiosita`, ho cercato di scoprire l'esatta dimensione dell'array
dopo la quale ottengo un segmentation fault: il seguente programma,
pero`, non da` i risultati sperati:
//// inizio pippo.cpp
//   nb: solo per gcc/g++
#include <iostream>
#include <exception>
long max_n;
void my_terminate()
{
  std::cout<<"dentro my_terminate: max_n="<<max_n<<"\n";
  abort();
}
void (*old_terminate)() = set_terminate(my_terminate);
int main() 
{
  for( max_n=long(1e6) ; ; max_n+=1000 )
    { 
      try { int v[max_n]; }
      catch(...){ std::cout<<"dentro catch: max_n="<<max_n<< "\n"; }
    }
}
//// fine pippo.cpp
In pratica, ho cercato di acchiappare (sia con catch che con
terminate) l'eccezione che porta al segmentation fault, per poter
stampare a video il valore di max_n prima dell'abort del programma.
Comunque non ci sono riuscito: infatti in output ottengo solo:
      0 [main] a 16529977 open_stackdumpfile: Dumping stack trace to
A.EXE.stackdump
Segmentation fault (core dumped)
Qualcuno sa perche`?
-- 
Ciao, Marvin


Appunto. Il problema e' che alcune delle cose che hai scritto nel
messaggio precedente sono fuorvianti: non e' detto che l'uso di memoria
dinamica porti ad un consumo di memoria piu' "mirato" di quanto non
avvenga usando variabili automatiche.
Ciao,
Nicola

 dinamici.
ti parlo di anni fa gli errori erano tanti ( e internet era solo un sogno)
star qui a riassumerteli tutti sarebbero troppi.
Se pensi che lo stak sia un buona soluzione,usalo.
ciao


ma chi ha parlato di uso di memoria più mirato ???
si parlava di gestione dello stack con array di grosse dimensioni solo di
quello.
ciao

 Qualcuno sa perche`?
Credo sia perchè alcune eccezioni (fra cui accesso alla memoria,
eccezioni FP, stack etc.) non sono gestite come eccezioni C++ e quindi
non possono essere catturate con catch. Non ricordo i dettagli ma
Windows definisce un suo meccanismo di gestione delle eccezioni (che è
simile ma non identico a quello del C++). Un programma che vuole gestire
tutte le eccezioni deve agganciarsi a tale meccanismo. Il compilatore
può farlo per te. Ma evidentemente non lo fa. Con il VC se non sbaglio
puoi controllare la cosa cone degli switch (tanto per cambiare).
Comunque ripeto: non ricordo i dettagli. E poi questo è OT. Chiedi su
ip.win32.


dimenticanza ma se poi vuoi credere quello che vuoi sei libero di farlo
Ok, ho visto. Molti messaggi mi sfuggono per mancanza di tempo.


 #include <vector>
Rispondo qui anche al resto della discussione ringraziando tutti
quelli che hanno risposto!
In realta' io stavo provando il valarray, e quello e' stato un problema
collaterale che e' saltato fuori.
Volevo valutare l' efficienza di usare un valarray in determinati casi
al posto di usare gli array "a mano"
Giusto per completezza posto il codice del test.
Ditemi che ne pensate.
Grazie!
#include <valarray>
#include <iostream>
#include <ctime>
using std::cout;
using std::cin;
using std::endl;
using std::clock_t;
using std::clock;
void numero();
int main()
{
 long i;
 clock_t start,end;
 cout << endl;
 cout << "std::valarray<double> punto1(10,10000000);" << endl;
 start=clock();
 std::valarray<double> punto1(10,10000000);
 end=clock();
 cout<<"Tempo impiegato= "<<double(end-start)<< " millisecondi" << endl
<<endl;
 cout << "punto1 *= 2;" << endl;
 start=clock();
 punto1 *= 2;
 end=clock();
 cout<<"Tempo impiegato= "<<double(end-start)<< " millisecondi" << endl <<
endl;
 cout << "puntov = new double[10000000]; e for(i=0; i<10000000; i++)
puntov[i]=10.0;" << endl;
 start=clock();
 double *puntov;
 puntov = new double[10000000];
 for(i=0; i<10000000; i++) puntov[i]=10.0;
 end=clock();
 cout<<"Tempo impiegato= "<<double(end-start)<< " millisecondi" << endl <<
endl;
 cout << "for(i=0; i<10000000; i++) puntov[i]*=2;" << endl;
 start=clock();
 for(i=0; i<10000000; i++) puntov[i]*=2;
 end=clock();
 cout<<"Tempo impiegato= "<<double(end-start)<< " millisecondi" << endl <<
endl;
 delete[] puntov;
}
--
Gerolamo