Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Dubbi sull'allocazione dinamica della memoria
Forum - C/C++ - Dubbi sull'allocazione dinamica della memoria

Avatar
ste_funk (Ex-Member)
Newbie


Messaggi: 4
Iscritto: 28/04/2006

Segnala al moderatore
Postato alle 14:49
Lunedì, 01/05/2006
Allora ragazzi.. volevo discutere un attimo sull'allocazione dinamica della memoria (malloc(), calloc(), blabla..) e del modo in cui il compilatore gestisce il tutto.

Analizziamo il seguente codice:
-----------------------------------------
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2.  
  3. char pnt[5];
  4.  
  5. int main(){
  6.  
  7.         scanf("%s", pnt);
  8.         printf("\nhai inserito: %s\n", pnt);
  9.  
  10.         return 0;
  11. }


-----------------------------------------

Teoricamente dovrebbe darmi un errore di Segmentatio Fault (o sbaglio?) all'inserimento di una stringa maggiore di 5 caratteri, cioè non possibile da contenere nell'array pnt[5].
Invece, compilando con Gcc sotto Linux, il programma accetta stringhe lunghe n senza andare in errore.
Primo quesito: dite che dipenda dal compilatore che utilizzo?

Secondo codice:
-----------------------------------------
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2.  
  3. char pnt[5];
  4.  
  5. int main(){
  6.  
  7.         scanf("%s", pnt);
  8.         printf("\nhai inserito: %s\n", pnt[6]);
  9.  
  10.         return 0;
  11. }


-----------------------------------------
Compilo senza problemi incuriosito dal risultato di prima, credendo magari in un ridimensionamento eseguito dal compilatore senza che io ne sappia nulla. A prima vista anche questo codice dovrebbe portare in errore, ma eseguendo ho notato questa cosa:
inserendo n caratteri, con 1 <= n <= 6 e cioè contenuti tra pnt[0] e pnt[5], il printf() mi restituisce solo un (null), senza nessuno errore. quando inserisco 7 o più caratteri e la posizione pnt[6] viene (teoricamente) riempita, mi ritorna un Segmentation Fault.
Secondo quesito: Perchè il compilatore, o il programma in esecuzione, non mi avverte prima di questa posizione non dichiarata (pnt[6])?

Gli stessi dubbi mi vengono con questo codice, modificato di poco, ma simile:
-----------------------------------------
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char *pnt;
  5. int i;
  6.  
  7. int main(){
  8.  
  9.         pnt=(char *)malloc(5*sizeof(char));
  10.         scanf("%s", pnt);
  11.  
  12.         for(i=0; i<10; i++)
  13.         printf("\nhai inserito: %c\n", pnt[i]);
  14.  
  15.         return 0;
  16. }


-----------------------------------------
Malloc alloca una zona di memoria definita per dimensioni dall'utente e restituisce un puntatore al primo byte di essa, correggetemi se sbaglio. Però anche qui non vi sono problemi se sforo da questa area dimensionata, mentre io pensavo di causare un errore.

Per non allungare troppo il post, aggiungerò dopo la seconda parte.

Ultima modifica effettuata da ste_funk il 01/05/2006 alle 19:40
PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6105
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 17:22
Lunedì, 01/05/2006
Testo quotato

Postato originariamente da ste_funk:

Teoricamente dovrebbe darmi un errore di Segmentatio Fault (o sbaglio?) all'inserimento di una stringa maggiore di 5 caratteri, cioè non possibile da contenere nell'array pnt[5].
Invece, compilando con Gcc sotto Linux, il programma accetta stringhe lunghe n senza andare in errore.
Primo quesito: dite che dipenda dal compilatore che utilizzo?




Assolutamente no, è compito del programmatore assicurarsi che le dimensioni dell'array siano sufficienti, se poi vengono inseriti dei dati che vanno oltre i limiti non viene generato nessun errore (almeno evidente), ma i dati vanno a sovrascrivere chissà quale area di memoria con conseguenze imprevedibili.

Testo quotato


Secondo quesito: Perchè il compilatore, o il programma in esecuzione, non mi avverte prima di questa posizione non dichiarata (pnt[6])?



Perchè il linguaggio C non prevede questo genere di avvertimenti a differenza di altri linguaggi come Java. Inoltre è scorretto chiamare printf passando %s come parametro (dovresti passare %c), visto che stampi: pnt[6] (che è un char, non un array di char).

Testo quotato


Malloc alloca una zona di memoria definita per dimensioni dall'utente e restituisce un puntatore al primo byte di essa, correggetemi se sbaglio.



Corretto.

Testo quotato


Però anche qui non vi sono problemi se sforo da questa area dimensionata, mentre io pensavo di causare un errore.



Se il C non ti avverte a compile-time vuoi che lo faccia a run-time? :asd:
Il tuo codice semplicemente va a leggere l'area di memoria immediatamente successiva a quella allocata, area che può contenere o no dati.


Seguimi su Twitter: http://www.twitter.com/pierotofy

Fai quello che ti piace, e fallo bene.
PM Quote
Avatar
Zizzius (Honoris User)
Guru


Messaggi: 675
Iscritto: 28/02/2005

Segnala al moderatore
Postato alle 19:19
Lunedì, 01/05/2006
Nulla da aggiungere :k:.

PM Quote
Avatar
ste_funk (Ex-Member)
Newbie


Messaggi: 4
Iscritto: 28/04/2006

Segnala al moderatore
Postato alle 19:30
Lunedì, 01/05/2006
Testo quotato

Postato originariamente da pierotofy:

Perchè il linguaggio C non prevede questo genere di avvertimenti a differenza di altri linguaggi come Java. Inoltre è scorretto chiamare printf passando %s come parametro (dovresti passare %c), visto che stampi: pnt[6] (che è un char, non un array di char).




Grazie per i chiarimenti, per quanto riguarda il %s nel printf() è stata una distrazione..8-|, ora continuo con le prove e vediamo se riesco a trovare qualcos'altro che non mi convince:k:

PM Quote
Avatar
ste_funk (Ex-Member)
Newbie


Messaggi: 4
Iscritto: 28/04/2006

Segnala al moderatore
Postato alle 19:41
Lunedì, 01/05/2006
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char *pnt;
  5. int k;
  6.  
  7. int main(){
  8.  
  9.         pnt=(char *)malloc(5*sizeof(char));
  10.         scanf("%s", pnt);
  11.  
  12.         for(k=0; k<10; k++)
  13.         printf("\nhai inserito: %c\n", pnt[k] );
  14.  
  15.         return 0;
  16. }



il codice del 3 esempio è questo sopra, nel post originale mi da un errore e non visualizza l'indice di pnt nell'ultima printf(). Strano, se provo a modificare il post è presente, ma non lo visualizza!

.modifica:
ho cambiato l'indice del for, con la variabile k, perchè utilizzando la i riconosceva l'indice dell'array come il tag del corsivo!:D

Ultima modifica effettuata da ste_funk il 01/05/2006 alle 19:45
PM Quote
Avatar
Zizzius (Honoris User)
Guru


Messaggi: 675
Iscritto: 28/02/2005

Segnala al moderatore
Postato alle 20:45
Lunedì, 01/05/2006
In effetti, pensavo fossero stati disattivati, i tag, all'interno dei codici sorgenti... :-|

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6105
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 21:28
Lunedì, 01/05/2006
Ehm.. temo di aver disabilitato solo le faccine. Appena ho tempo do' un'occhiata. :-|


Seguimi su Twitter: http://www.twitter.com/pierotofy

Fai quello che ti piace, e fallo bene.
PM Quote