Newsgroup: it.comp.lang.c++
Titolo: strutture dati e array

Dopo un'accanita discussione sulle limitazioni del Pascal sulle strutture
dati a lezione, mi chiedevo se in C/C++ esistesse il modo di dichiarare un
array (o simile) con un numero indefinito di elementi. Io credo di no perchè
mi sebra strano riuscire a riservare uno spazio di memoria (che in quanto
tale è finito) per un numero indefinito di oggetti. Fatemi sapere.
Forse non ce n'è bisogno ma vi consiglio di non installare la beta 2 di
Explorer 5 perchè è stata in grado di bloccarmi il PC in modo tale che non
si spegnesse nemmeno schiacciando il pulsante (case ATX). Fatelo per la
salute della macchina...
--
San Vegeta from Hell
http://www.geocities.com/Area51/Dungeon/8436
http://come.to/Fantasy.it

 salute della macchina...
Me ne guardo bene.
EMG

 tale è finito) per un numero indefinito di oggetti. Fatemi sapere.
[...]
Premetto che in qualità di autodidatta rischio di dirti qualche eresia  ...
spero che nell'eventualità qualcun'altro mi corregga
Credo ci siano diversi modi per fare una allocazione dinamica nello HEAP di un
vettore.
Io di solito in C uso una funzione tipo malloc (o faralloc per puntatori far).
/* esempio di un vettore di caratteri */
char *vettore;
vettore = (char) malloc(sizeof(char)*la_mia_dimensione);
/*                ^----------------- malloc ritorna un void che bisogna castare)
*/
if(vettore==NULL) return 0; /* qualcosa è andato storto */
/*.
 codice di esecuzione vario ...
.*/
free(vettore); /* libera la memoria. nota*/
--------------------------------------------
la cosa è molto più elegante in C++ perchè per fare una allocazione dinamica è
sufficiete:
char *vettore;
vettore = new char(mia_dimensione);
/*.
 codice di esecuzione vario ...
.*/
delete vettore; // libera la memoria
P.S.
bisogna utilizzare gli include adeguati.
Ciao Lucio.

tale è finito) per un numero indefinito di oggetti. Fatemi sapere.
Non e` possibile allocare oggetti di dimensione indefinita a compile time, non sarebbero
trattabili. In caso di allocazione statica il compilatore deve essere in grado di
determinare la dimensione dell'oggetto, se non altro per creare correttamente il
segmento dati; se la dimensione di un array puo` essere nota solo a run time,
e` necessario ricorrere ad una allocazione dinamica.
Non si tratta di una limitazione del pascal, e` semplicemente cosi` per tutti i
linguaggi compilati.
Un tale comportamento puo` pero` essere simulato, realizzando una struttura
capace di espandersi e contrarsi dinamicamente. In C++ strutture di questo
genere fanno parte della libreria standard, in pascal invece devi realizzartele
da solo.
Paolo
----------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
  e-mail: 
mar...@cli.di.unipi.it
 
----------------------------------------------------------

 bisogna utilizzare gli include adeguati.
Bastano i normalissimi stdlib.h per malloc e compagnia e iostream.h per
new.
EMG

 In C il cast non solo non č necessario ma č anzi deleterio.
Grazie delle correzioni, ma perchč mi dici che non si deve fare il (cast*) sul
puntatore ritornato da malloc che "dovrebbe" essere un void?
Comunque sono d'accordo sul fatto che i cast siano deleteri almeno cosě dicono...
Ossequi.
    By Lucio

puntatore ritornato da malloc che "dovrebbe" essere un void?
In C (NON in C++), void* si trasforma automaticamente in
qualsiasi T* serva, per qualsivoglia tipo T.  Meglio dunque, in
C, non fare il cast perche` cosi` non si sbaglia (ad esempio
tu hai castato, non a char* come intendevi, ma a char; per
fortuna il compilatore ti sgriderebbe, se no...:-).  In C++,
naturalmente, e` diverso (meglio usare new, non malloc,
se possibile).
Sia in C, sia in C++, e` assolutamente garantito dai relativi
standard che sizeof(char) e` identicamente eguale a 1, per
cui non e` necessario moltiplicare per sizeof(char) (non che
faccia alcun danno, ma, anche qui, non mettere codice del
tutto ridondante puo` evitare eventuali errori).
Alex

bisogna utilizzare gli include adeguati.
Non occorre utilizzare alcun include particolare per new e delete[].
Alex

tale č finito) per un numero indefinito di oggetti. Fatemi sapere.
Infatti mica "riservi" lo spazio di memoria alla definizione del vettore
(men che meno alla sua _dichiarazione_!); lo "riservi", con le opportune
funzioni-membro (anzitutto vettore.reserve(), ma anche, implicitamente,
vettore.resize(), vettore.push_back(), eccetera), man mano che sei
interessato a cambiarlo (averne quantita` maggiori o minori a tua
disposizione entro vettore).
Se, in un dato istante, "pretendi troppo" rispetto alle risorse della tua
macchina (o a quella frazione di tali risorse che e` accedibile dal tuo
specifico processo, se l'allocazione di risorse di memoria virtuale
sulla piattaforma che usi e` soggetta a "quote"), ad esempio chiami
    vettore.resize(10000000);
quando non puo` essere reso disponibile un blocco di dieci milioni
per sizeof(int) [40 milioni di byte sulla maggior parte delle attuali
piattaforme], ti ritrovi in una "situazione eccezionale": e questo, in
C++ Standard, viene appunto gestito "sollevando una eccezione"
(che il tuo codice puo`, e dovrebbe, gestire opportunamente con
il costrutto try/catch; se scegli di non gestirla, l'eccezione potra`
determinare la terminazione anomala del programma "troppo
avido", sperabilmente con una diagnostica adeguata).
Alex

 Comunque sono d'accordo sul fatto che i cast siano deleteri almeno così dicono...
Sono in generale deleteri in quanto forzano il compilatore ad operare
delle conversioni indipendentemente da ogni tipo di controllo statico
che, in mancanza, avrebbe correttamente effettuato.
EMG

Perché il C converte implicitamente un void * in qualsiasi altro tipo.
Fortunatamente, solo in un _puntatore_; in altri termini:
    void* pv;
    int i;
    i = pf;
NON causa conversione implicita neppure in C.
Alex

 NON causa conversione implicita neppure in C.
Chiaro. Avevo dato la cosa per scontata.
EMG