Oppure

Loading
18/10/05 17:41
Nophiq
Volevo chiedere alcune cose sulla funzione malloc:
da quello che ho capito scrivendo:

- int *p;
- p = (int*) malloc (5*sizeof(int));

faccio in modo di occupare della memoria; ma non equivale ad inizializzare un array di int di 5 valori? ovvero queste due righe di codice non si possono riassumere in:

- int array[5];
aaa
18/10/05 17:46
Nophiq
Vorrei commentare un programma a proposito:

#include <stdio.h>
#include <stdlib.h>

main () {
 float *v;
 int n;

 printf("Inserisci la dimensione: ");
 scanf("%d", &n);

 v = (float*) malloc(n*sizeof(float));
 ... uso dell'array ...
 free(v);
}


Tutto questo non si potrebbe riassumere in

#include <stdio.h>
#include <stdlib.h>

main () {
 int n;

 printf("Inserisci la dimensione: ");
 scanf("%d", &n);

 [b]float v[n];[/b]
 ... uso dell'array ...
}
Ultima modifica effettuata da Nophiq 18/10/05 17:46
aaa
19/10/05 12:31
pierotofy
Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.
Il mio blog: piero.dev
19/10/05 15:19
Zizzius
Esatto: come dice Piero, non ? possibile, in C, istanziare variabili se non all'inizio di un blocco. Quindi, quando un programmatore ha la necessit? di istanziare variabili di dimensioni che dipendono da condizioni dettate dalla stesso blocco, ? necessario allocare dinamicamente la memoria. Un valido esempio di questo meccanismo ? il tuo stesso programma, Nophiq: posto che si deve istanziare un vettore di lunghezza dipendente da una scelta dell'utente, si possono seguire due strade:

1) il programmatore poco avveduto (cio?, che non ha ancora studiato l'allocazione dinamica :asd: ) - o come insegnano a scuola :-| - istanzier? un vettore di lunghezza fissata arbitrariamente:
main()
{
   float v[100];
}
Una cosa del genere ? stata insegnata alla mia classe giusto luned? scorso... ma questo pu? causare uno spreco della memoria eccedente da un lato, e un overflow se, viceversa, si superano il limite della dimensione del vettore (o comunque, la mancanza di spazio per eventuali ulteriori dati da memorizzare);

2) il programmatore che vuole fare le cose per bene... proceder? invece come segue:
main()
{
int n;
float *v;

printf("Inserisci il numero di elementi: "); /* o simile */
scanf("%d", &n);

v =(float *) calloc(n, sizeof(float)); /* trattandosi di vettori si pu? usare la funzione calloc, molto simile a malloc */
}



Esiste anche un altro utilizzo dell'allocazione dinamica della memoria. Come tutti sappiamo, una funzione pu? ricevere pi? di un parametro, ma pu? restituire un solo valore: ma nel caso vi sia la necessit? di restituire un vettore, come si pu? aggirare questa regola? Con l'allocazione dinamica!
All'interno della funzione viene allocato dinamicamente un vettore (questo meccanismo ? valido ovviamente anche per le stringhe) e viene restituito il puntatore a tale vettore; vediamo un esempio:

#include <stdlib.h>
#include <string.h>

/* funzione che esegue la copia di una stringa; restituisce un puntatore alla nuova stringa */
char *strdup(const char *s1)
{
	int i=0;
   char *s2 =(char *) calloc(strlen(s1), sizeof(char));

   for (i = 0; i < strlen(s1); i++)
   	s2[i] = s1[i];
   s2[i] = 'Esatto: come dice Piero, non ? possibile, in C, istanziare variabili se non all'inizio di un blocco. Quindi, quando un programmatore ha la necessit? di istanziare variabili di dimensioni che dipendono da condizioni dettate dalla stesso blocco, ? necessario allocare dinamicamente la memoria. Un valido esempio di questo meccanismo ? il tuo stesso programma, Nophiq: posto che si deve istanziare un vettore di lunghezza dipendente da una scelta dell'utente, si possono seguire due strade:


1) il programmatore poco avveduto (cio?, che non ha ancora studiato l'allocazione dinamica :asd: ) - o come insegnano a scuola :-| - istanzier? un vettore di lunghezza fissata arbitrariamente:
main()
{
   float v[100];
}
Una cosa del genere ? stata insegnata alla mia classe giusto luned? scorso... ma questo pu? causare uno spreco della memoria eccedente da un lato, e un overflow se, viceversa, si superano il limite della dimensione del vettore (o comunque, la mancanza di spazio per eventuali ulteriori dati da memorizzare);

2) il programmatore che vuole fare le cose per bene... proceder? invece come segue:
main()
{
int n;
float *v;

printf("Inserisci il numero di elementi: "); /* o simile */
scanf("%d", &n);

v =(float *) calloc(n, sizeof(float)); /* trattandosi di vettori si pu? usare la funzione calloc, molto simile a malloc */
}



Esiste anche un altro utilizzo dell'allocazione dinamica della memoria. Come tutti sappiamo, una funzione pu? ricevere pi? di un parametro, ma pu? restituire un solo valore: ma nel caso vi sia la necessit? di restituire un vettore, come si pu? aggirare questa regola? Con l'allocazione dinamica!
All'interno della funzione viene allocato dinamicamente un vettore (questo meccanismo ? valido ovviamente anche per le stringhe) e viene restituito il puntatore a tale vettore; vediamo un esempio:

#include <stdlib.h>
#include <string.h>

/* funzione che esegue la copia di una stringa; restituisce un puntatore alla nuova stringa */
char *strdup(const char *s1)
{
	int i=0;
   char *s2 =(char *) calloc(strlen(s1), sizeof(char));

   for (i = 0; i < strlen(s1); i++)
   	s2[i] = s1[i];
   s2[i] = '{parsed_message}';

   return s2;
}


Questo utilizzo dell?allocazione dinamica ? possibile in quanto il tempo di vita delle variabili istanziate dinamicamente cessa solo con la chiamata alla funzione free() e la loro visibilit? dura finch? sono puntate .

:alert: Un fattore assolutamente importante da tener presente ? il seguente: dopo un?allocazione dinamica, bisogna ricordarsi di verificare che l?allocazione abbia avuto successo, ovvero che sia stata trovata sufficiente memoria nell?heap per eseguire l?operazione di allocazione dinamica:

#include <stdio.h>
#include <stdlib.h>

/* ... il vettore [i]v[/i] ? stato allocato dinamicamente ... */

if (v == NULL) {
   printf(?Memoria non disponibile per completare le operazioni.\n?);
   exit(EXIT_FAILURE);
}



Spero di aver risolto i tuoi dubbi :k: ( :ot: ma se speri di superarmi nelle Olimpiadi di Informatica, ti sbagli... :rotfl: ...scherzo! ).
'; return s2; }


Questo utilizzo dell?allocazione dinamica ? possibile in quanto il tempo di vita delle variabili istanziate dinamicamente cessa solo con la chiamata alla funzione free() e la loro visibilit? dura finch? sono puntate .

:alert: Un fattore assolutamente importante da tener presente ? il seguente: dopo un?allocazione dinamica, bisogna ricordarsi di verificare che l?allocazione abbia avuto successo, ovvero che sia stata trovata sufficiente memoria nell?heap per eseguire l?operazione di allocazione dinamica:

#include <stdio.h>
#include <stdlib.h>

/* ... il vettore [i]v[/i] ? stato allocato dinamicamente ... */

if (v == NULL) {
   printf(?Memoria non disponibile per completare le operazioni.\n?);
   exit(EXIT_FAILURE);
}



Spero di aver risolto i tuoi dubbi :k: ( :ot: ma se speri di superarmi nelle Olimpiadi di Informatica, ti sbagli... :rotfl: ...scherzo! ).
Ultima modifica effettuata da Zizzius 19/10/05 15:21
aaa
19/10/05 16:08
Rand
Nophiq...

...x lo stesso effetto (ma in c++), puoi usare l'operatore "new"... x allocare dinamicamente la memoria!;)

Questo programma qua sotto (in c++) equivale a quello che hai fatto tu in c (x l'array di 5 elementi):

#include <iostream>
using namespace std;

int main() {
int dim; //dimensione dell'array
int *array; //puntatore int alla prima cella dell'array (che verr? creato in seguito)

//chiedo all'utente di che dimensione vuole l'array
cout<<"Inserisci la dimensione dell'array: ";
cin>>dim;

//alloco dinamicamente l'array con l'operatore new
array=new int[dim]

//da qua in poi... lo puoi usare come se fosse un semplice array[dim] ...esempio...
for(int i=0; i<dim; i++) {
  cout<<"Inserisci l'ele num "<<i+1<<" dell'array: ";
  cin>>array[i];
}
// e poi fai tutto il resto...

return 0;
}



...lo so che forse non ti serve sapere il c++ :-| ...ma secondo me ? meglio che se stai imparando il c, lo confronti con la sua versione migliorata... il c++!! 8-|


ciaooo :k:
aaa
19/10/05 16:20
Rand
Postato originariamente da pierotofy:

Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.


:-| ...non sono d'accordo con Piero! ...e nemmeno con zizzius! :-|

...io il c lo faccio da una vita... e non mi ha mai dato problemi sul fatto di aver dichiarato variabili anche in mezzo a un blocco di istruzioni! 8-| ...non condivido quello che avete detto... :-|

...questo programma lo dimostra (compilato con successo su dev-c++ 4.9.9.0 x win32 con gcc 3.44)...

#include <stdio.h>

int main() {
int i=2;
    printf("I vale: %d\n", i);
int k=3;
    printf("K vale: %d\n", k);
char c='f';
    printf("C vale: %c\n", c);
 
return 0;
}


...forse il problema sta che ora i compilatori di c... accettano anche istruzioni proprie del c++ :-|
Ultima modifica effettuata da Rand 19/10/05 16:22
aaa
19/10/05 20:49
pierotofy
Infatti ;)

Se i compilatori fanno i comodi loro senza rispettare lo standard ANSI e lasciano la possibilit? di dichiarare le variabili anche dopo un blocco di istruzioni non ? colpa di nessuno :asd:
Ultima modifica effettuata da pierotofy 19/10/05 20:50
Il mio blog: piero.dev
19/10/05 20:59
Nophiq
Postato originariamente da Zizzius:
non ? possibile, in C, istanziare variabili se non all'inizio di un blocco.


Era quello che stavo cercando, il mio parere riguardo all'inizializzazione del vettore non all'inizio proviene dal Java...

Grazie :k:
aaa