Curiosità sui puntatori

di il
57 risposte

57 Risposte - Pagina 4

  • Re: Curiosità sui puntatori

    oregon ha scritto:


    Weierstrass ha scritto:


    nicolap ha scritto:



    TROLL detected!
    Non è un troll, è il classico niubbi che compila ed esegue senza debuggare passo passo per rendersi conto di cosa stia accadendo
    Il vero problema è l'ignoranza (nel senso di ignorare, non conoscere)... non ha la minima idea di quello che scrive perché non l'ha studiato e/o capito
    nella programmazione reale i puntatori li so usare molto ma molto bene
    il mio vero problema è che voglio spingermi oltre alle cose fritte e rifritte!
    e come potevi capiere anche dal titolo oltre che dagli esempi non pratici che ho fatto
    era una curiosità su un problema teorico e non un problema reale!
    mi scuso di averti fatto perdere tempo.
    vedro di approfondire l'argomento da qualche altra parte.
    grazie per le risposte che mi hai dato.
  • Re: Curiosità sui puntatori

    Anche se non ho trovato la risposta e visto che non si approda a nulla di costruttivo.
    chiedo scusa per il tempo che vi ho fatto perdere
    grazie a tutti
    se vole per me il tred puo anche essere chiuso
  • Re: Curiosità sui puntatori

    smalldragon ha scritto:


    Anche se non ho trovato la risposta e visto che non si approda a nulla di costruttivo.
    chiedo scusa per il tempo che vi ho fatto perdere
    grazie a tutti
    se vole per me il tred puo anche essere chiuso
    La risposta te l'ho data: cosa non ti è chiaro sulle 7 righe di codice che ho scritto?
  • Re: Curiosità sui puntatori

    @smalldragon, dalle domande che fai, non sembra proprio!

    Le questioni sono:

    1) non hai capito come funzionano i puntatori
    2) stai cercando una specifica risposta che conferma una tua idea, ma tale idea e' errata.

    Quando allochi, DEVI SPECIFICARE quanto allocare, NON C'E' MODO DI NON FARLO.
    Quando giochi con i puntatori, se fai pasticci il sistema se ne accorge SOLO quando lo metti in crisi in qualche modo.
    NON C'E' MODO di prevenire i pasticci.

    Quando allochi, il sistema SA quanto hai allocato.
    Quando liberi, il sistema ricupera le informazioni precedenti e libera correttamente
    SE passi alla funzione di allocazione un puntatore CHE NON E' STATO ALLOCATO , metti il sistema in crisi, perche' lui usa ricupera delle informazioni che sono inconsistenti.
    In generale, la quantita' di memoria allocata e' un informazione che sta' un po di byte PRIMA dell'indirizzo di memoria rappresentato dal puntatore. Queste NON SONO informazioni disponibili all'utente. Se usi la malloc/calloc, ci dovrebbe essere la _msize(). Se usi la "new" del C++, la cosa e' molto piu' complicata perche' in C++ c'i sono i metodi virtuali e l'ereditarieta' multipla. Quindi, comedeallocare lo sa la "delete", ma le info sono accessibili solo all'IMPLEMENTAZIONE della "delete"

    SE scrivi oltre la quantita' di memoria allocata, metti il sistema in crisi
    Se scrivi d un indirizzo a casaccio, metti il sistema in crisi
    Il sistema NON SA a che cosa punta VERAMENTE il puntatore quando lo usa, lui SI FIDA di quello che hai specificato in fase di scrittura del sorgente e del fatto che lo usi correttamente.

    OGNI ALTRO strano uso, se non fatto con "STRA COGNIZIONE DI CAUSA" mette in crisi il sistema.

    Il "STRA COGNIZIONE DI CAUSA" sta' ad indicare che per poter fare qualcosa di "strano" DEVI muoverti con i piedi di piombo, cioe' in modo da non corrompere le strutture dati di servizio del gestore dello heap, di non andare a leggere ad inidirizzi NON ASSEGNATI al processo, oppure in cui non hai il diritto di leggere, di non andare a scrivere ad indirizzi in cui c'e' il codice, ecc

    Se cerchi altre risposte, prova a fare una domanda piu' circostanziata!
  • Re: Curiosità sui puntatori

    Weierstrass ha scritto:


    smalldragon ha scritto:


    Weierstrass ha scritto:


    A parte che sarebbe b==0

    a ha dimensioni 4 byte o 8 byte (dipende se l'architettura è a 32 bit o 64) e sta puntando a 0. Stai tentando di scrivere in un'area vietata
    è stata distrazione il non mettere l'altro =!
    comunque a non stà puntando a 0, e di conseguenza non è un area vietata, ma sta puntando ad un indirizzo ben specifico + 0 .... altri incrementi.
    infatti se compili il programma, a parte la mancanza dell'altro =, il programma funziona e va in loop eterno.
    Sta puntando a zero, anzi a zero + zero: è un po' presuntuso da parte tua fare affermazioni senza conoscere bene l'argomento, non credi?
    	
    char b; // 1 byte allocato nello stack
    char * a; // 4 o 8 byte allocati nello stack: in quei 4 byte c'è scritto 0, quindi a punta a zero
    
    a = &b; // adesso in quei quattro byte di a hai scritto l'indirizzo di memoria dello stack dove è allocata b; a punta a b
    
    *a = 'X'; // b = 'X'
    
    a = new char[5]; // il kernel dell'OS ha allocato 5 byte nella memoria heap dove vuole lui (dove ha trovato spazio libero)
    // a e' stato riscritto e punta esattamente a quell'area di memoria
    
    delete[] a; // l'area dello heap dove puntava a è stata liberata
    quello che non mi è chiaro e che centra con il problema teorico che ho espresso?
    in quanto tu leghi il puntatore ad una variabile che ti definisci nello heap con dimensioni ben specifiche. (secondo caso)
    leghi il puntatore ad una variabile con dimensioni ben specifiche e con dimensioni ben specifiche. (primo caso)
    il quale non è il caso cui i menziono.
    in quanto, vedi anche esempi che faccio,il caso cui menziono e l'uso non associato del puntatore.
    comunque grazie lo stesso.
  • Re: Curiosità sui puntatori

    smalldragon ha scritto:


    Per capirci
    nel caso più banale del mondo e cioè
    
    int b;
    char *a;
    int c;
    c=0;b=0;
    while (b=0)
    { a[c]=' '; c++; }
    
    premesso il ciclo è stato fatto a posta per essere infinito per dare l'opportunita alla variabile a di travolgere la variabile c!
    in questo caso come faccio a capire la dimensione della variabile a?
    Intanto, la variabile 'a' ha la dimensione di un puntatore!

    La dimensione dell'area di memoria PUNTATA dal puntatore memorizzato in 'a' e' un'informazione NON ACCESSIBILE al programmatore.

    E' RESPONSABILITA' del programmatore ASSICURARSI di usare in modo corretto il puntatore.

    Se a te serve avere questa informazione, DEVI implementarti un allocatore "custom".

    In C/C++ ci sono dei metodi per rimpiazzare la malloc/calloc/free, che sono alla base ANCHE della "new/new[]/delete/delete[]"

    SE ad 'a' allochi un blocco di memoria allocato con la malloc/calloc, LO PUOI liberare con la free, e probabilmente riesci a ricuperare la dimensione con la "_msize()"

    SE ad 'a' allochi un blocco di memoria con la new/new[], LO DEVI liberare con la delete/delete[] (STESSO tipo), e NON HAI ACCESSO all'informazione relativa a quanta memoria e' stata allocata (la _msize NON FUNZIONA perche' il puntatore che ottieni NON E' lo stesso che e' stato ritornato dalla "malloc" usata nell'implementazione della "new/new[]"

    Questo in GENERALE, poi c'e' il caso in cui allochi tipi primitivi, in questo caso la new/delete si dovrebbe comportare esattamente come la malloc/free

    RICORDA: IL C NON INIZIALIZZA LE VARIABILI! Quindi il contenuto di QUALUNQUE VARIABILE, appena dichiarara e NON ESPLICIATEMEN inizializzata, e' PURA SPORCIZIA.

    PUOI AVERE il colpo di C... che l'area di memoria conteneva ZERO, MA IN GENERALE NON TE LO ASSICURA NESSUNO.


    Di nuovo: se le risposte non ti garbano, fai domande migliori!
  • Re: Curiosità sui puntatori

    migliorabile ha scritto:


    @smalldragon, dalle domande che fai, non sembra proprio!

    Le questioni sono:

    1) non hai capito come funzionano i puntatori
    2) stai cercando una specifica risposta che conferma una tua idea, ma tale idea e' errata.

    Quando allochi, DEVI SPECIFICARE quanto allocare, NON C'E' MODO DI NON FARLO.
    Quando giochi con i puntatori, se fai pasticci il sistema se ne accorge SOLO quando lo metti in crisi in qualche modo.
    NON C'E' MODO di prevenire i pasticci.

    Quando allochi, il sistema SA quanto hai allocato.
    Quando liberi, il sistema ricupera le informazioni precedenti e libera correttamente
    SE passi alla funzione di allocazione un puntatore CHE NON E' STATO ALLOCATO , metti il sistema in crisi, perche' lui usa ricupera delle informazioni che sono inconsistenti.
    In generale, la quantita' di memoria allocata e' un informazione che sta' un po di byte PRIMA dell'indirizzo di memoria rappresentato dal puntatore. Queste NON SONO informazioni disponibili all'utente. Se usi la malloc/calloc, ci dovrebbe essere la _msize(). Se usi la "new" del C++, la cosa e' molto piu' complicata perche' in C++ c'i sono i metodi virtuali e l'ereditarieta' multipla. Quindi, comedeallocare lo sa la "delete", ma le info sono accessibili solo all'IMPLEMENTAZIONE della "delete"

    SE scrivi oltre la quantita' di memoria allocata, metti il sistema in crisi
    Se scrivi d un indirizzo a casaccio, metti il sistema in crisi
    Il sistema NON SA a che cosa punta VERAMENTE il puntatore quando lo usa, lui SI FIDA di quello che hai specificato in fase di scrittura del sorgente e del fatto che lo usi correttamente.

    OGNI ALTRO strano uso, se non fatto con "STRA COGNIZIONE DI CAUSA" mette in crisi il sistema.

    Il "STRA COGNIZIONE DI CAUSA" sta' ad indicare che per poter fare qualcosa di "strano" DEVI muoverti con i piedi di piombo, cioe' in modo da non corrompere le strutture dati di servizio del gestore dello heap, di non andare a leggere ad inidirizzi NON ASSEGNATI al processo, oppure in cui non hai il diritto di leggere, di non andare a scrivere ad indirizzi in cui c'e' il codice, ecc

    Se cerchi altre risposte, prova a fare una domanda piu' circostanziata!
    anche se a te non sembra l'uso dei puntatori lo conosco molto molto bene
    ripeto per l'ennesima volta finchè le dimensioni sono certe sia legando il puntatore a memoria allocata che a variabili con dimensione nota non c'è problema.
    quello che vorrei capire, senza legare il puntatore, e come evitare che il sistema vada in crisi e nel caso come "aiutarlo" ad uscire dalla crisi! e soprattutto che non vada a ricoprire altre variabili
    comunque, se ben ricordo, nel caso in cui un puntatore tenti di accedere a memoria non allocata il sistema genera un eccezione e si leva dalla crisi terminando il programma
  • Re: Curiosità sui puntatori

    Ma lo leggi quello che scriviamo?

    NON LO PUOI FARE!

    NON C'E' MODO DI FARLO

    NON SE PO' FA'

    NIET!

    Oppure, si puo fare, MA NON COME PENSI TU!!!!

    DEVI CAMBIARE linguaggio di programmazione e passare ad uno che non ti permette di usare i puntatori direttamente!

    C#, Java, Python, Julia, ...

    (anche se, con le giuste conoscenze (o lor mancanza ), si possono fare casini ANCHE con questi linguaggi )

    Nota: "levarlo dalla crisi" mediante terminazione, NON E' levarlo dalla crisi, ma "ammazzarlo"
    "levarlo dalla crisi" vuol dire, che e' in grado di continuare a funzionare, altrimenti dove starebbe il divertimento?
  • Re: Curiosità sui puntatori

    smalldragon ha scritto:


    il quale non è il caso cui i menziono.
    in quanto, vedi anche esempi che faccio,il caso cui menziono e l'uso non associato del puntatore.
    comunque grazie lo stesso.
    ascolta, ma l'hai provato davvero il tuo caso oppure no?

    Se ti risulta diversamente che dopo "char * a;" a non punti a zero e che, quindi, o ti blocchi su un runtime error quando fai "*a = 'X';" oppure il programma tenta di scrivere 'X' all'indirizzo zero (con reazioni diverse a seconda del processore/OS), allora postane le prove con tanto di screenshot del disassembly.
  • Re: Curiosità sui puntatori

    Non so dove andrai a trovare risposte ma per il c ri diranno che NON PUOI. Se non lo capisci boh che ti devo dire?

    P.S. si scrive thread non tred
  • Re: Curiosità sui puntatori

  • Re: Curiosità sui puntatori

    OVVIAMENTE, un programmatore ESPERTO, con un BEL PO' di conoscenze, puo' metter in campo TUTTA UNA SERIE di strategie, che lo puo' aiutare a CONTROLLARE se sta' usando bene i puntatori.

    MA per farlo DEVE seguire tutta una seie di REGOLE MOOOOLTO stringenti, e qesto MITIGA, ma NON ANNULLA i problemi.
  • Re: Curiosità sui puntatori

    Tutto questo per il linguaggio.

    TUTTA ALTRA STORIA se utilizzi il supporto del sistema operativo. Ad esempio Windows mette a disposizione un filtro per le eccezioni e potresti anche scrivere
    
    #include <windows.h>
    #include <stdio.h>
    
    int *p;
    
    LONG WINAPI e(LPEXCEPTION_POINTERS ExceptionInfo) {
    	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
    	{
    		DWORD codeBase = (DWORD)GetModuleHandle(NULL);
    		printf("Accesso in memoria vietato all'indirizzo %X\n", p);
    
    		return EXCEPTION_CONTINUE_EXECUTION;
    	}
    
    	return EXCEPTION_EXECUTE_HANDLER;
    }
    
    int main() {
    	LPTOP_LEVEL_EXCEPTION_FILTER h = SetUnhandledExceptionFilter(e);
    	
    	p = NULL;
    	while (*p) { printf("OK %X\n", p); p++; }
    
    	return 0;
    }
    Ma RIPETO ... TUTTA UN'ALTRA STORIA e vale SOLO per l'accesso a zone di memoria non allocate al processo.
    La sovrascrittura non è individuabile se non usando controlli puntali di indirizzi delle variabili (come ti ho detto con l'operatore &) che all'atto prativo risulterebbero pesantissimi.
Devi accedere o registrarti per scrivere nel forum
57 risposte