Oppure

Loading
01/05/06 12:49
ste_funk
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:
-----------------------------------------
#include <stdio.h>

char pnt[5];

int main(){

	scanf("%s", pnt);
	printf("\nhai inserito: %s\n", pnt);

	return 0;
}

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

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:
-----------------------------------------
#include <stdio.h>

char pnt[5];

int main(){

	scanf("%s", pnt);
	printf("\nhai inserito: %s\n", pnt[6]);

	return 0;
}

-----------------------------------------
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:
-----------------------------------------
#include <stdio.h>
#include <stdlib.h>

char *pnt;
int i;

int main(){

	pnt=(char *)malloc(5*sizeof(char));
	scanf("%s", pnt);

	for(i=0; i<10; i++)
	printf("\nhai inserito: %c\n", pnt[i]);

	return 0;
}

-----------------------------------------
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 01/05/06 17:40
aaa
01/05/06 15:22
pierotofy
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.

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).

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


Corretto.

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.
Il mio blog: piero.dev
01/05/06 17:19
Zizzius
Nulla da aggiungere :k:.
aaa
01/05/06 17:30
ste_funk
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:
aaa
01/05/06 17:41
ste_funk
#include <stdio.h>
#include <stdlib.h>

char *pnt;
int k;

int main(){

	pnt=(char *)malloc(5*sizeof(char));
	scanf("%s", pnt);

	for(k=0; k<10; k++)
	printf("\nhai inserito: %c\n", pnt[k] );

	return 0;
}


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 01/05/06 17:45
aaa
01/05/06 18:45
Zizzius
In effetti, pensavo fossero stati disattivati, i tag, all'interno dei codici sorgenti... :-|
aaa
01/05/06 19:28
pierotofy
Ehm.. temo di aver disabilitato solo le faccine. Appena ho tempo do' un'occhiata. :-|
Il mio blog: piero.dev