[C++]Dubbio gestione eccezione bad_alloc

di il
3 risposte

[C++]Dubbio gestione eccezione bad_alloc

Salve, ho un dubbio in merito alla gestione dell'eccezione bad_alloc.
ho la necessità di riallocare un array per aumentare la sua dimensione massima.
creo quindi un array temporaneo di dimensione doppia rispetto a quella dell'array di partenza e verifico se l'allocazione è andata a buon fine o meno.
in quest'ultimo caso però come mi comporto? dovrei terminare il programma? cancello l'array temporaneo che non è stato allocato?
questo è il codice:

void Tavolo::realloc(void)
{
	carteTot *= 2;
	Carta *temp = NULL;

	try
	{
		temp = new Carta[carteTot];
	}
	catch (bad_alloc&)
	{
		cerr << "Impossibile riallocare l'array." << endl;
		delete[] temp;
		temp = NULL;
		carteTot /= 2;
	}

	for (int i = 0; i < carteAttuali; i++)
		temp[i] = carte[i];

	delete[] carte;
	carte = temp;
}
come si può vedere dopo il try-catch effettuo la copia dell'array originale in quello con la dimensione doppia; tuttavia è corretto fare questa copia al di fuori del try-catch? se temp non venisse allocato correttamente questo codice darebbe problemi?

3 Risposte

  • Re: [C++]Dubbio gestione eccezione bad_alloc

    Qui di seguito come la vedo io, magari altri ti possono dare risposte più precise.
  • Re: [C++]Dubbio gestione eccezione bad_alloc

    In generale è molto difficile che un vettore non venga allocato, era un problema comune con le modalità a 16 bit, ora a 32bit capita per vettori sopra il gigabyte, per 64bit spesso il limite effettivo (per Windows) è dell'ordine di qualche decina di gigabyte.
    Quindi, nel caso specifico, un messaggio del tipo "houston abbiamo un problema" ci può stare, con terminazione anche piuttosto brutale.

    Invece sul programma ti segnalo che invece di fare *2 e /2 puoi fare (nel primo caso) una somma (o addirittura uno shift), così come nel secondo caso. i++ normalmente viene scritto ++i

    I consigli dati sopra sono condivisibili: fai tornare un flag. magari potresti perfino mettere un parametro (flag) in ingresso del tipo i_silente (default:falso) che se settato fa apparire messaggi di log, ti servirà per un eventuale debug (ovviamente non in questo caso banale, intendo in situazioni più complesse)
  • Re: [C++]Dubbio gestione eccezione bad_alloc

    candaluar ha scritto:


    Dipende da te: la funzione realloc potrebbe ritornare un booleano per indicare che la realloc è riuscita oppure no, lasciando a più alto livello la segnalazione all'utente che la memoria è esaurita; oppure potresti sollevare allo stesso modo un'eccezione da raccogliere e gestire a più alto livello
    in effetti penso sia la cosa più furba ritornare un bool.

    candaluar ha scritto:


    Se il buffer non è stato allocato devi uscire, non lo puoi utilizzare; non c'è bisogno di try/catch, se il buffer non è stato allocato lo sai e quindi esci dalla funzione.
    ora che ci penso hai ragione, anziché usare un try/catch (che a quanto so è abbastanza oneroso in termini di prestazioni) penso che risolverei il problema meglio con il classico "if (pointer == NULL) ....".

    +m+ ha scritto:


    In generale è molto difficile che un vettore non venga allocato, era un problema comune con le modalità a 16 bit, ora a 32bit capita per vettori sopra il gigabyte, per 64bit spesso il limite effettivo (per Windows) è dell'ordine di qualche decina di gigabyte.
    Quindi, nel caso specifico, un messaggio del tipo "houston abbiamo un problema" ci può stare, con terminazione anche piuttosto brutale.
    beh, una volta c'ero riuscito: ero curioso su cosa stampasse il messaggio d'errore dell'eccezione (e.what()) allora ho fatto un for che da capacità 5 continuava a riallocare l'array per 100 volte e alla fine il povero debugger mi dice "memoria esaurita"

    +m+ ha scritto:


    Invece sul programma ti segnalo che invece di fare *2 e /2 puoi fare (nel primo caso) una somma (o addirittura uno shift), così come nel secondo caso. i++ normalmente viene scritto ++i
    in effetti non so quanto sia logico un *2 (l'avevo scritto perché non mi veniva in mente): dato che questo tavolo gestisce un tavolo di scopa penso sia inutile raddoppiare ogni volta la dimensione, bensì possa essere sufficiente incrementarla soltanto di 1.
    sul ++i/i++ però ho un dubbio: in un for non va messo i++? perché altrimenti i verrebbe incrementato prima di iniziare il ciclo for, o sbaglio?
Devi accedere o registrarti per scrivere nel forum
3 risposte