Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180

    [C++] array e aritmetica dei puntatori

    c'è qualcosa che non mi torna...
    se dichiaro un array di 10 elementi, viene allocata memoria solo e soltanto per quei dieci elementi...

    se per caso dovessi assegnare un dato valore ad un ipotetico undicesimo elemento, commetterei un errore logico, in quanto questo valore verrebbe scritto in una zone di memoria che non so a cosa corrisponde...

    codice:
    int prova_array[] = { 1, 2, 3, 4 };
    for (int i = 0; i < 4; i++) {
        cout << prova_array[i] << '\n';
    }
    cout << '\n';
    
    for (int i = 0; i < 4; i++) {
        cout << *(prova_array + i) << '\n';
    }
    cout << '\n';
    questo codice fa tranquillamente il suo lavoro stampando tutti i valori dell'array, sia incrementando l'indice che usando l'aritmetica dei puntatori


    a questo punto però provo a scrivere
    codice:
    prova_array[7] = 15;
    for (int i = 0; i < 8; i++) {
        cout << prova_array[i] << '\n';
    }
    cout << '\n';
    
    for (int i = 0; i < 8; i++) {
        cout << *(prova_array + i) << '\n';
    }
    cout << '\n';
    e maledizione funziona anche questo codice

    ovviamente i valori di prova_array[4], [5] e [6] sono presi non so dove dallo stack, ma il valore [7] corrisponde a quello che ho immesso io...

    se una cosa del genere posso (forse) capirla incrementando l'indice, utilizzando l'aritmetica dei puntatori proprio non mi ritrovo
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2002
    Messaggi
    173
    questo succede perchè quando crei un vettore il compilatore si occupa lui dell'allocazione di tutti i suoi elementi nello stack, perciò anche se te immetti effettivamente un valore in una sola cella le altre sono comunque inizializzate con un valore qualsiasi, che sarà molto raramente 0, e comunque vi sarà sempre un valore, questo per la natura della memoria ram, e che dovrebbe dipendere anche dal compilatore.
    Ora, anche se te usi l'aritmetica dei puntatori è la medesima cosa, in quanto nella tua memoria la struttura dell'array c'è quindi accedi tranquillamente via via dalla prima all'ultima cella del vettore!!

    nome_vettore | -1211313 |
    nome_vettore + 1 | -1211313 |
    nome_vettore + 2 | -1211313 |
    nome_vettore + 3 | -1211313 |
    nome_vettore + 4 | -1211313 |
    nome_vettore + 5 | -1211313 |
    nome_vettore + 6 | -1211313 |
    nome_vettore + 7 | 15 |

    la struttura della tua memoria a grandi linee (tenendo conto che ogni elemento del vettore occupa 4 celle di memoria o 2 in base che sia di tipo int o short, o altre dipendentemente dal tipo di dato) e come quella sopra con tutti i valori inizializzati con un valore random, ma comunque effettivamente presenti nella memoria. Il fatto che il compilatore crei questa struttura è legato all'uso che si fa della ram. Spero di aver chiarito un pò i tuoi dubbi ma soprattutto di essere stato corretto!!!

    CIAO

  3. #3
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da eagle_fly
    questo succede perchè quando crei un vettore il compilatore si occupa lui dell'allocazione di tutti i suoi elementi nello stack, perciò anche se te immetti effettivamente un valore in una sola cella le altre sono comunque inizializzate con un valore qualsiasi, che sarà molto raramente 0, e comunque vi sarà sempre un valore, questo per la natura della memoria ram, e che dovrebbe dipendere anche dal compilatore.
    Ora, anche se te usi l'aritmetica dei puntatori è la medesima cosa, in quanto nella tua memoria la struttura dell'array c'è quindi accedi tranquillamente via via dalla prima all'ultima cella del vettore!!

    nome_vettore | -1211313 |
    nome_vettore + 1 | -1211313 |
    nome_vettore + 2 | -1211313 |
    nome_vettore + 3 | -1211313 |
    nome_vettore + 4 | -1211313 |
    nome_vettore + 5 | -1211313 |
    nome_vettore + 6 | -1211313 |
    nome_vettore + 7 | 15 |

    la struttura della tua memoria a grandi linee (tenendo conto che ogni elemento del vettore occupa 4 celle di memoria o 2 in base che sia di tipo int o short, o altre dipendentemente dal tipo di dato) e come quella sopra con tutti i valori inizializzati con un valore random, ma comunque effettivamente presenti nella memoria. Il fatto che il compilatore crei questa struttura è legato all'uso che si fa della ram. Spero di aver chiarito un pò i tuoi dubbi ma soprattutto di essere stato corretto!!!

    CIAO
    nello stack dovrei avere una cosa del genere
    array0 | 1
    array1 | 2
    array2 | 3
    array3 | 4

    una volta che scrivo prova_array[7] = 15, perchè questo si accoda automaticamente ad array3??? ho provato anche ad inizializzare altre var nel mezzo, giusto per occupare un po' di spazio, ma il risultato non cambia...

    prova_array[7] dovrebbe essere allocato in un una cella a caso dello stack, chissà dove... invece continua a finire subito dopo array3
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  4. #4
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    uso MInGW come compilatore. e il valore 15 che dai alla ottava locazione dell'array non va a finire subito dopo prova_array[3], ma va nell'ottava locazione; questo è l'output del programma , prima di andare in crash a causa dell'accesso errato in memoria:

    1
    2
    3
    4
    4008320
    0
    2293680
    15


    come vedi le prime quattro locazioni sono quelle correttamente inizializzate con la dichiarazione dell'array; poi ci sono tre posizioni, dalla quinta alla settima, che hanno dei valori a caso, e infine l'ottava, corroispondente a prova_array[7], che ha il valore 15; l'output è lo stesso anche con l'aritmetica dei puntatori; anzi in genere i compilatori trasformano automaticamente a[i] in *(a + i)

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  5. #5
    Utente di HTML.it L'avatar di netarrow
    Registrato dal
    Apr 2004
    Messaggi
    1,425
    la memoria è obbligatoria allocarla solo nel caso dei puntatori, il tuo array contiene valori.

    Se dichiari:

    int* a;//LA MEMORIA NON E' ALLOCATA E TANTO MENO INIZIALIZZATA

    int a;//la memoria è allocata ma non inizializzata

    Come esempio riporto un programma che ha un array di puntatori a interi:

    codice:
    #include <iostream>
    
    using namespace std;
    
    int main() {
    	int     a = 1;
    	int	b = 2;
    	int	c = 3;
    	int	d = 4;
    	int      t = 5;
    	int *q[] = {&a,&b,&c,&d};
    
    	q[5] = &t;
    
    	for(int i = 0; i < 5; i++) {
    		cout << *q[i] << " ";
    	}
    
    
    	return 0;
    }
    Eseguendo normalmente, vediamo scrivere: 1 2 3 4... e il 5? Non si vede, allora facciamo un debug e... eccolo! Access Violation! E l'indirizzo incriminato è proprio lui: 0xC0000005.
    Quindi avremo:

    0xC0000001 = 1
    0xC0000002 = 2
    0xC0000003 = 3
    0xC0000004 = 4
    ----------------
    0xC0000005 = 5// gli do il valore 5 senza aver allocato => Access Violation


    Ho fatto adesso gli esperimenti, e nella speranza di non aver detto cacate, ciao
    Imparare è un'esperienza, tutto il resto è solo informazione. (Albert Einstein)

  6. #6
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da anx721
    uso MInGW come compilatore. e il valore 15 che dai alla ottava locazione dell'array non va a finire subito dopo prova_array[3], ma va nell'ottava locazione; questo è l'output del programma , prima di andare in crash a causa dell'accesso errato in memoria:
    appunto... non dovrebbe essere nell'ottava locazione, ma in una a caso

    io uso devcpp e il prog non abortisce
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  7. #7
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    appunto... non dovrebbe essere nell'ottava locazione, ma in una a caso
    E perchè mai?

    In C non si effetuano a runtime controlli sui limiti degli array, quindi quando scrivi

    a[i] = xxx ;

    il compilatore sa semplicemente che deve scrivere il valore xxx nella i-esima locazione a partire da quella puntata da 'a', non in una posizione a caso; se poi questa locazione apartiene o meno all'array non importa, sta al programmatore occuparsi di questo. Quindi se tu scrivi

    prova_array[7] = 15

    il compilatore va a scrivere nell'ottava posizione di memoria (tenendo conto della dimensione degli int) a partire dalla locazione puntata dal puntatore prova_array, il fatto che tale locazione non appartenga piu all'array ma chissa a cosa è ignoto al compilatore, che si limita a effettuare la scrittura;

    quindi non c'è nulla di cui stupirsi.

    Dev-cpp non è un compilatore, ma semplicemente un editor, che viende distribuito generalmente assieme ad un compilatore, che nelle ultime versioni è proprio MinGW; nelle versioni precedenti non so con che compilatore venisse distribuito. Il verificarsi o meno del crash puo dipedere dal compilatore e/o dal sistema operativo.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  8. #8
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da anx721
    E perchè mai?

    In C non si effetuano a runtime controlli sui limiti degli array, quindi quando scrivi

    a[i] = xxx ;

    il compilatore sa semplicemente che deve scrivere il valore xxx nella i-esima locazione a partire da quella puntata da 'a', non in una posizione a caso; se poi questa locazione apartiene o meno all'array non importa, sta al programmatore occuparsi di questo. Quindi se tu scrivi

    prova_array[7] = 15

    il compilatore va a scrivere nell'ottava posizione di memoria (tenendo conto della dimensione degli int) a partire dalla locazione puntata dal puntatore prova_array, il fatto che tale locazione non appartenga piu all'array ma chissa a cosa è ignoto al compilatore, che si limita a effettuare la scrittura;

    quindi non c'è nulla di cui stupirsi.

    Dev-cpp non è un compilatore, ma semplicemente un editor, che viende distribuito generalmente assieme ad un compilatore, che nelle ultime versioni è proprio MinGW; nelle versioni precedenti non so con che compilatore venisse distribuito. Il verificarsi o meno del crash puo dipedere dal compilatore e/o dal sistema operativo.
    il secondo capoverso del mio primo post l'ho preso pari pari da
    INTRODUZIONE ALLA PROGRAMMAZIONE ED ELEMENTI DI STRUTTURE DATI CON IL LINGUAGGIO C++, pag 115, cap 9.2
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  9. #9
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Originariamente inviato da hfish
    il secondo capoverso del mio primo post l'ho preso pari pari da
    INTRODUZIONE ALLA PROGRAMMAZIONE ED ELEMENTI DI STRUTTURE DATI CON IL LINGUAGGIO C++, pag 115, cap 9.2

    Immagino che ti riferisci a questo:

    se per caso dovessi assegnare un dato valore ad un ipotetico undicesimo elemento, commetterei un errore logico, in quanto questo valore verrebbe scritto in una zone di memoria che non so a cosa corrisponde...
    Questa frase non significa che la locazione di memoria in cui vado a scrivere non so quale sia...la locazione di memoria in cui scrivo la so e come...ed è appunto quella che ottengo a partire dal puntatore e andando avanti per 11 posizioni, ed è il meccanismo che usa il compilatore per scrivere in un array, idipendentemente dal fatto che l'indice in cui vado a scrivere sia o no entro i limiti dell'array stesso. l'espressione:

    "questo valore verrebbe scritto in una zona di memoria che non so a cosa corrisponde"

    significa invece che quella locazione in cui vado a scrivere non so cosa contenga, se è una locazione che è stata riservata per un altra variabile, se non è ancora utilizzata dal programma, o se ci sono altri dati; in ogni caso è un errore che puo causare il crash del programma

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  10. #10
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da anx721
    Immagino che ti riferisci a questo:



    Questa frase non significa che la locazione di memoria in cui vado a scrivere non so quale sia...la locazione di memoria in cui scrivo la so e come...ed è appunto quella che ottengo a partire dal puntatore e andando avanti per 11 posizioni, ed è il meccanismo che usa il compilatore per scrivere in un array, idipendentemente dal fatto che l'indice in cui vado a scrivere sia o no entro i limiti dell'array stesso. l'espressione:

    "questo valore verrebbe scritto in una zona di memoria che non so a cosa corrisponde"

    significa invece che quella locazione in cui vado a scrivere non so cosa contenga, se è una locazione che è stata riservata per un altra variabile, se non è ancora utilizzata dal programma, o se ci sono altri dati; in ogni caso è un errore che puo causare il crash del programma
    ok, ora ho capito... interpretavo male la frase io...

    grazi x il tempo perso...
    auguri
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

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.