Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2011
    Messaggi
    10

    [C]Domanda nuda e cruda

    Sempre sulle malloc, mi sta venendo un dubbio parecchio atroce:

    char* alloca (int n){
    char* stringa = malloc (n * sizeof(char));
    return stringa;
    }

    int main(int argc, char* argv[]){
    char* miaStringa = alloca (1);
    miaStringa[0] = 'a';
    }

    Ha senso? Oppure la memoria allocata da malloc viene liberata all'uscita della funzione? Non riesco a trovare una risposta chiara a riguardo...
    Grazie mille.

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Oppure la memoria allocata da malloc viene liberata all'uscita della funzione?
    La memoria allocata dinamicamente *deve* essere deallocata esplicitamente dal programmatore con la funzione free(), non viene deallocata in automatico all'uscita dallo scope di una funzione; questo dipende dalle diverse aree di memoria in cui viene allocato lo spazio richiesto nel caso dell'allocazione statica (stack) e dinamica (heap): il primo si ridimensiona automaticamente alla chiamata di una funzione e alla sua terminazione, il secondo deve essere ridimensionato manualmente dal programmatore con apposite chiamate di sistema (invocate tramite funzioni di libreria), questo almeno in C/C++.

    PS: scegli titoli più significativi per i thread.
    every day above ground is a good one

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2011
    Messaggi
    10
    Avrei editato il titolo ma son passati 60 minuti e non me lo fa fare (O_O)
    Cmq grazie della risposta... Anche se la mia domanda era un po' diversa credo che indirettamente tu mi abbia risposto lo stesso...
    Quindi io quando assegno 'a' a miaStringa[0] non sto accedendo ad un punto "a caso" della memoria no? diciamo... gli "effetti" della malloc permangono anche al di fuori della funzione dove la malloc viene chiamata giusto?

    Perchè io da qualche parte avevo trovato che una funzione come

    char* alloca(int n){
    char stringa[n];
    return stringa;
    }

    Non aveva senso, e mi chiedevo se viceversa utilizzando una malloc era possibile creare una funzione simile...

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Originariamente inviato da Fingard
    Quindi io quando assegno 'a' a miaStringa[0] non sto accedendo ad un punto "a caso" della memoria no? diciamo... gli "effetti" della malloc permangono anche al di fuori della funzione dove la malloc viene chiamata giusto?
    No, non è un punto a caso, è una locazione di memoria appositamente allocata nell'heap con la chiamata alla malloc(), ammesso ovviamente che questa sia andata a buon fine (e per questo è sempre preferibile verificare che il puntatore restituito dalla funzione non sia NULL, stesso discorso per calloc()). Rimarrà allocata fino a quando non la deallochi esplicitamente con free() (o in teoria anche con realloc() passando 0 come nuovo size) o comunque fino a quando non terminerà il processo, caso in cui il sistema operativo provvederà automaticamente a reclamare l'intero spazio in memoria allocato per il processo appena terminato.

    Originariamente inviato da Fingard
    Perchè io da qualche parte avevo trovato che una funzione come
    [...]
    In quel modo la memoria per la stringa viene deallocata al momento dell'uscita dalla funzione, quindi se accedi da main() all'indirizzo restituito non hai alcuna garanzia che quell'area di memoria non sia già stata sovrascritta. Tra l'altro fai attenzione al fatto che l'allocazione di un array/stringa con size variabile non è consentita dal C "tradizionale" (ISO C90) ma è un'estensione del C99, tra l'altro non supportata da tutti i compilatori.
    every day above ground is a good one

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2011
    Messaggi
    10
    Perfetto, grazie mille... Ora inizia a essere più chiaro... Anche se il C per me rimane ancora parecchio misterioso...

    Risalendo all'indietro con delle stampe mi sono accorto che il mio problema, o almeno uno dei problemi, è che quando ho

    ...
    char** bigBuffer = NULL;
    bigBuffer = malloc(sizeof(char*));
    bigBuffer[0] = malloc (50 * sizeof(char));
    printf("%i\n", (int) strlen(bigBuffer[0]));
    ...

    Questo stampa 6 -_-'
    IMMEDIATAMENTE dopo la malloc... Se io poi vado a scrivere su bigBuffer[0] una stringa >= 6 non c'è problema (i chars "nati dal nulla" vengono sovrascritti) ma se ci scrivo ad esempio "sai" mi ritrovo dentro bigBuffer "saiXXX" dove gli XXX sono i vecchi chars (che il mio terminale stampa con dei caratteri indecifrabili)...
    Qualcuno ha idea di come questo sia possibile? Da qualche altra parte nel codice sono andato a scrivere dove non si dovrebbe?

  6. #6
    strlen lavora sulle stringhe
    un array di char però non è per forza una stringa
    un array di char diventa una stringa se e solo se è presente un terminatore di stringa in una qualsiasi delle sue posizioni ('\0')


    se chiami una strlen su un array di char non inizializzato e senza che tu abbiap osto in un punto preciso il terminatore di stringa, il risultato che ottieni è totalmente imprevedibile e dipende da quanto vi fosse precedentemente scritto in quella determinata locazione di memoria


    per la cronaca, la malloc si limita semplicemente a renderti disponibile una determinata porzione di memoria, ma non te la inizializza a nessun valore, bensi vi lascia al suo interno quanto precedentemente vi fosse

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2011
    Messaggi
    10
    Ecco perfetto... Ora tutto inizia ad avere senso... Lo stesso discorso varrà anche per strcat, che io uso alla fine per rimettere insieme tutte le (non) stringhe di bigBuffer in un testo unico... e da qui tutti i casini a cascata... Bene, ora ho capito perchè il mio codice aveva comportamenti "un tantino" imprevedibili... Grazie delle spiegazioni...
    Il fatto è che avendo programmato (sol)tanto in java continuo a prendere per buone equivalenze non vere (tipo
    "per allocare una stringa hai bisogno di un char* s = malloc (k * sizeof(char))"
    uguale a
    "se char* s = malloc(k * sizeof(char)), s è una stringa")...

  8. #8

    Re: [C]Domanda nuda e cruda

    Originariamente inviato da Fingard
    Sempre sulle malloc, mi sta venendo un dubbio parecchio atroce:

    char* alloca (int n){
    char* stringa = malloc (n * sizeof(char));
    return stringa;
    }
    cambia il nome della funzione in NewString, cosi' al chiamante è chiaro che deve rilasciarla; alloca può essere fuorviante, infatti in alcuni SO ci sono delle API che si chiamano alloc e che liberano automaticamente all'uscita dei blocchi.

    Dato che ci sei, siccome hai una NewString, crea anche una FreeStringIf del tipo:
    codice:
    char * FreeStringIf (char * theString){
    	if (NULL != theString){
    		free (theString);
    	}
    	return NULL;
    }
    che puoi ad esempio utilizzare così:
    codice:
    int main (void){
    	char * aString = NewString (1024);
    	if (NULL != aString){
    	// your program is handling the good string..
    	
    	}
    	aString = FreeStringIf (aString);
    	return 0;
    }

  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296

    Moderazione

    Originariamente inviato da Fingard
    [C]Domanda nuda e cruda
    Per favore, usa titoli più significativi per le discussioni in futuro, come da Regolamento.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.