2015-04-28 19 views
7

Per esempio:Come si scorre attraverso un puntatore?

int *start; 
start = (int*)malloc(40); 

Se volessi scorrere tutti i 40 byte, come farei così? Ho provato a fare qualcosa di simile:

while(start != NULL){ 
    start++; 
} 

ma che scorre un massiccio numero di valori, che è molto più grande di 40. Così, come si fa a garantire che si scorrere attraverso tutti i 40 byte.

Grazie per tutto l'aiuto.

+2

Non vedo il motivo per cui non ho votato la domanda, ci sono input e sforzi ragionevoli per mostrare cosa l'OP vuole fare. Cosa è successo a SO ultimamente – fayyazkl

+0

Non riesco a ricordare la logica, ma lo cerco su SO. Non si dovrebbe mai trasmettere il risultato restituito da malloc. Rimuovere il (int *) dalla riga start = ... malloc ...; – rhubarbdog

+0

Deve essere insegnato piuttosto che ridimensionato silenziosamente. Il motivo è disponibile in dettaglio in altre domande su SO, ma è possibile che il valore di ritorno di cast di malloc POSSIBILMENTE nasconda/manometta un'allocazione fallita. Si noti che questo è specifico per C. In C++, è un requisito per farlo. – fayyazkl

risposta

6

Ci sono due problemi qui.

Un singolo ptr ++ salta come molti byte del tipo di elemento a cui punta.

Qui tipo è int, quindi sarebbe saltare 4 byte per volta (assumendo una macchina a 32 bit dal numero intero di 4 byte (32 bit) là).

Se volete scorrere tutti i 40 byte (un byte alla volta), iterare utilizzando dire un tipo di dati char (o di tipo gettato la tua int * a char * e quindi incrementare)

L'altro problema è il tuo ciclo di terminazione.

Qui non c'è nessuno che mette un NULL alla fine, quindi il ciclo continuerà a funzionare (e il puntatore avanza in avanti) fino a quando non viene eseguito può essere un null o esce dall'area di memoria assegnata e si blocca. Il comportamento non è definito.

Se sono stati assegnati 40 byte, è necessario terminare a 40 byte.

Aggiornamento:

Sulla base di un commento sperma in votazione alla domanda iniziale, vale la pena ricordare che tipo di getto il risultato di malloc non è una buona idea in C. Il motivo principale è che esso potrebbe potenzialmente manomettere un'allocazione fallita. È un requisito in C++ però. I dettagli possono essere trovati nella stessa identica domanda su SO. Cerca "casting valore di ritorno di malloc"

+0

Il tipo non è stato definito da me (dal professore), e quindi deve essere un int. C'è un modo che potrei passare attraverso i byte con un int? – svsav

+0

Stavo aggiornando la risposta, vedi che – fayyazkl

+0

puoi sempre trasmettere un int a un char e poi fare un ++. Voglio intenzionalmente che tu lo provi, invece di scriverlo qui sotto – fayyazkl

1

Gli array rappresentano blocchi contigui di memoria. Poiché il nome dell'array è fondamentalmente un puntatore al primo elemento, è possibile utilizzare la notazione dell'array per accedere al resto del blocco. Ricorda però, non ci sono errori nel controllo di C sui limiti dell'array, quindi se ti allontani dalla fine del blocco di memoria, puoi fare tutto ciò che non hai inteso e più che probabile finirà con una sorta di errore di memoria o errore di segmentazione. Dal momento che l'int può essere di dimensioni variabili, vorrei utilizzare questo codice invece:

int *start; 
int i; 

start = malloc(40 * sizeof(int)); 

for (i = 0; i < 40; i++) 
    { 
    start[i] = 0; 
    } 

Qualcosa del genere funzionerà bene. Il modo in cui lo stai facendo, almeno dal codice che hai postato, non c'è modo di fermare il ciclo perché una volta superato il blocco di memoria, continuerà fino a quando non verrà eseguito un NULL o si verificherà un errore di memoria. In altre parole, il ciclo uscirà solo se viene eseguito un valore nullo. Quella null può essere all'interno del blocco di memoria che hai assegnato, o potrebbe essere ben oltre il blocco.

EDIT: Una cosa che ho notato del mio codice.Alloca lo spazio per 40 pollici che possono essere 4 byte, 8 byte o qualcos'altro a seconda dell'architettura della macchina su cui si sta lavorando. Se si vuole veramente solo 40 byte di numeri interi, quindi fare qualcosa di simile:

int *start; 
int i; 
int size; 

size = 40/sizeof(int); 
start = malloc(size); 
for (i = 0; i < size; i++) 
    { 
    start[i] = 0; 
    } 

Oppure si può utilizzare un tipo di dati char o un unsigned char se è necessario. Un'altra cosa che ho notato. La funzione malloc restituisce un tipo di puntatore vuoto che è compatibile con tutti i puntatori, quindi non è necessario eseguire un typecast su un malloc.

+0

Si potrebbe voler cambiare 'punti' in puntatori nella prima riga. Inoltre è meglio dire "Array decadono in puntatori in termini di accesso". La matrice non è un puntatore e viceversa – fayyazkl

+0

l'ho visto e l'ho corretto. Non sono d'accordo con la terminologia dell'array però. Il modo in cui ho imparato è che gli array sono fondamentalmente dei puntatori. Il puntatore punta a un blocco di memoria e si utilizza la notazione array per accedere a diverse aree di quel blocco. –

+0

Gli array non sono puntatori. Questo è uno dei malintesi più comuni trovati in giro. Anche in questo caso, l'esatta affermazione corretta è "Il decadimento del nome dell'array in puntatore al primo elemento", qui finisce la somiglianza. Si prega di leggere qualche buona referenza. Se necessario posso certamente suggerire anche – fayyazkl

4

Prima di tutto, si dovrebbe essere assegnando int s correttamente:

int* start = malloc(sizeof(int)*40) ; 

Quindi è possibile utilizzare matrice indicizzazione di:

for(size_t i = 0 ; i < 40 ; i++) 
{ 
    start[i] = 0 ; 
} 

o un puntatore alla fine della memoria allocata:

int* end = start+40 ; 
int* iter = start ; 

while(iter < end) 
{ 
    *iter= 0 ; 
    iter++ ; 
} 
+0

Quale è meglio? – grisevg

0

Well array in C non sono limitati, alcune opzioni, il più commo n:

int *start; 
int cnt = 0; 
start = (int*)malloc(sizeof(int)*40);; 

while(cnt<40) 
{ 
    start++; 
    cnt++; 
} 

Un'altra opzione:

int *start; 
int *ref; 
start = ref = (int*)malloc(sizeof(int)*40); 

while(start != ref+40) 
    start++; 

E quest'ultimo è più vicino a quello che ti sembra di dire a che fare:

int *start; 
start = ref = (int*)malloc(sizeof(int)*41); 
start[40] = -1; 

while((*start) != -1) 
    start++; 

Vorrei suggerire la lettura di più su come puntatori in C lavoro. Non sembri averne un'ottima conoscenza. Inoltre, ricorda che C toglie le ruote di addestramento. Le matrici non sono limitate o terminate in un modo standard e un puntatore (indirizzo in memoria) non sarà mai NULL dopo l'iterazione attraverso una matrice e il contenuto a cui punta il puntatore potrebbe essere qualsiasi cosa.

Problemi correlati