Strumenti Utente

Strumenti Sito


fisica:informatica:201718:esercitazioni:esercitazione8

Esercitazione allocazione dinamica

Esercizio 1: Sequenze e VLA

Realizzare un programma C che legge e memorizza in un VLA una sequenza di double di lunghezza non nota a tempo di compilazione (ma nota all'utente a tempo di esecuzione). Richiedere all'utente di specificare la lunghezza prima di immettere la sequenza.

Esercizio 2: Sequenze e malloc()

Modificare la soluzione all'esercizio 1 in modo da utilizzare la funzione malloc() per allocare l'array dopo aver letto la lunghezza.

Verificare la corretta allocazione e gestire gli errori.

Esercizio 3: Allocazioni in grossi blocchi

Eseguire il seguente programma C

#include <stdio.h>
#include <stdlib.h>
#define SIZE 10000000000
 
int main (void) {
  double * h;
 
  h = malloc(SIZE*sizeof(double));
 
  if ( h == NULL ) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }
 
  printf("Allocato h = %p\n",(void *) h);
 
  return 0;
}

cosa succede ? Cercate di capire che cosa succede quando va in esecuzione perror() andando a verificare il manuale (sezione 3 man 3 perror)

Esercizio 4: realloc()

Modificare la soluzione all'esercizio 2 in modo da utilizzare la funzione relloc() per fare crescere dinamicamente l'array senza richiedere la lunghezza della sequenza.

Verificare la corretta allocazione e gestire gli errori.

Esercizio 5: Effetti collaterali indesiderati

Se ho una variabile intera “int i”, posso modificarne il valore con una funzione che riceve un puntatore “&i” (di tipo int * ) alla cella di memoria di “i”.

Allo stesso modo, se ho un array di interi int * a, posso modificarne il valore, ovvero creare un nuovo array a cui a e' un riferimento con una funzione che riceve un puntatore &a (di tipo int * * ) alla cella di memoria di a.

Le due funzioni array1() e array2() qui sotto tentano di fare proprio questo. Tuttavia, dopo aver inizializzato l'array B notiamo che il contenuto dell'array A e' cambiato. Qual'e' il motivo di questo comportamento? (suggerimento: guardare le slides su VLA)

#include <stdio.h>

// questa funzione riceve un puntatore ad un array di interi, ed ha il compito di creare un array in qu
void array1(int ** c);

// questa funzione si comporta come array1 ma crea un array differente
void array2(int ** c);


int main(){

	int * aA; // array A
	int * aB; // array B

	array1(&aA);

	printf("array A: %d, %d, %d \n",aA[0],aA[1],aA[2]);

	array2(&aB);

	printf("array B: %d, %d, %d \n",aB[0],aB[1],aB[2]);

	// ma nel frattempo, cosa e' successo all'array A?
	printf("array A: %d, %d, %d \n",aA[0],aA[1],aA[2]);

    return 0;
}


void array1(int ** c){

	int n = 3;

// avendo usato a[n], la dimensione non e' nota a tempo di compilazione
// quindi non possiamo utilizzare la costruzione con valore letterale "a[n] = {1,2,3}"
	int a[n];  

	a[0] = 1; 
	a[1] = 2; 
	a[2] = 3;

	*c = a;
}

void array2(int ** c){
	int n = 3;
	int a[n];

	a[0] = 4;
	a[1] = 5;
	a[2] = 6;

	*c = a;
}

Correggere il codice in modo che le funzioni array1() e array2() allochino i rispettivi array sullo heap con la funzione “malloc()”, e venga quindi evitato l'effetto collaterale di B su A.

Esercizio 6: Funzione di allocazione/deallocazione di matrici

Le matrici possono essere rappresentate come array di puntatori a righe. Si richiede di implementare le funzioni per la creazione e la deallocazione di matrici nxm di double. In particolare, la funzione

/** crea una matrice di double rappresentata come array di puntatori a righe
  \param n numero di righe
  \param m numero di colonne
  
  \retval NULL se si e' verificato un errore 
  \retval p puntatore alla matrice allocata altrimenti
  */
double ** mat_new (unsigned n, unsigned m);

crea una matrice con n righe ed m colonne e ne restituisce il puntatore. E

/** libera la memoria occupata da una matrice di double rappresentata come array di puntatori a righe
  \param a puntatore alla matrice da deallocare
  \param n numero di righe
  
  */
void mat_free (double** a, unsigned n);

Sviluppare un opportuno main che testa che l'allocazione e la deallocazione siano stata effettuata correttamente, anche in caso di errori in corso d'opera.

fisica/informatica/201718/esercitazioni/esercitazione8.txt · Ultima modifica: 06/03/2019 alle 13:53 (16 mesi fa) da Susanna Pelagatti