2012-11-10 9 views
33

Capisco leggermente quale sia la definizione di memset(). Tuttavia, non capisco a cosa serve.Memset Definizione e utilizzo

Definizione: imposta i primi num byte del blocco di memoria indicato da ptr sul valore specificato (interpretato come un carattere senza segno).

Quindi questo codice univoco è un valore in un indirizzo di memoria?

memset(&serv_addr,0,sizeof(serv_addr) è l'esempio che sto cercando di capire.

Qualcuno può spiegare in modo MOLTO semplificato?

+2

Viene principalmente utilizzato per inizializzare le strutture e gli array. – imreal

+0

quindi è come dire array [valore]? perché non farlo in quel modo però, che senso ha usare memset? –

+0

Puoi farlo come 'array [valore]' solo se conosci il valore di 'value' durante il tempo di compilazione (questo è C/C++). – irrelephant

risposta

38

memset() è una versione molto veloce di un'operazione relativamente semplice:

void* memset(void* b, int c, size_t len) { 
    char* p = (char*)b; 
    for (size_t i = 0; i != len; ++i) { 
     p[i] = c; 
    } 
    return b; 
} 

Cioè, memset(b, c, l) impostare le l byte a partire dall'indirizzo b al valore c. Lo fa molto più rapidamente rispetto all'implementazione di cui sopra.

+1

Stranamente, hai un inizializzatore C++ ma un cast C ... – Neil

+0

@Neil: buon punto - Sono una persona C++ e ho realizzato che mi affido alla conversione. Cambierò il codice per essere sia C che C++. –

+0

Come codificato, la tua funzione ha un comportamento definito dall'implementazione perché 'c' potrebbe non rientrare nell'intervallo per il tipo' char'. Dovresti invece definire 'p' come' unsigned char * p = (unsigned char *) b; '(il cast è necessario solo in C++). – chqrlie

26

memset() viene in genere utilizzato per inizializzare i valori. Per esempio si consideri il seguente struct:

struct Size { 
    int width; 
    int height; 
} 

Se si crea uno di questi sullo stack in questo modo:

struct Size someSize; 

Poi i valori che struct stanno per essere undefined. Potrebbero essere zero, potrebbero essere i valori che si trovano lì da quando quella parte della pila è stata usata per l'ultima volta. Quindi di solito si dovrebbe seguire quella linea con:

memset(&someSize, 0, sizeof(someSize)); 

Naturalmente può essere utilizzato per altri scenari, questo è solo uno di loro. Basti pensare ad esso come un modo per impostare semplicemente una porzione di memoria su un determinato valore.

+2

Data la domanda che chiede quale sia il punto di memset, questa risposta è migliore di quella accettata. –

3

Immagino che serv_addr è una variabile locale o globale di qualche tipo struct -Forse struct sockaddr - (o forse un class).

&serv_addr sta prendendo l'indirizzo di quella variabile. È un indirizzo valido, dato come primo argomento a memset. Il secondo argomento su memset è il byte da utilizzare per il riempimento (zero byte). L'ultimo argomento a memset è la dimensione, in byte, di quella zona di memoria da riempire, che è la dimensione di quella variabile serv_addr nell'esempio.

Quindi questa chiamata a memset cancella una variabile globale o locale serv_addr contenente alcuni struct.

In pratica, il GCC compilatore, quando sta ottimizzando, genererà il codice intelligente per questo, di solito srotolamento e inlining esso (in realtà, è spesso un builtin, così GCC può generare codice molto intelligente per esso).

5

memset è un modo comune per impostare un'area di memoria su 0 indipendentemente dal tipo di dati. Si può dire che memset non si preoccupa del tipo di dati e imposta semplicemente tutti i byte a zero.

IMHO in C++ si dovrebbe evitare di fare memset quando possibile poiché aggira il tipo di sicurezza fornito da C++, invece si dovrebbe usare il costruttore o l'inizializzazione come mezzo di inizializzazione. memset fatto su un'istanza di classe può anche distruggere qualcosa involontariamente:

ad es.

class A 
{ 
public: 
    shared_ptr<char*> _p; 
}; 

un memset in un'istanza di quanto sopra non farebbe un contatore di decremento riferimento correttamente.

+1

Questa risposta dovrebbe essere più in alto nella lista. Non è sicuro usare memset in C++. – mwm314

1

Non è altro che impostare la memoria su un valore particolare.

Ecco il codice di esempio.

Memset (const * p, unit8_t V, unit8_t L), Qui P è il puntatore alla memoria di destinazione, V è il valore del buffer di destinazione che verrà impostato su un valore V el è la lunghezza del dati.

while(L --> 0) 
{ 
    *p++ = V; 
} 
+0

Bel esempio di downto to operator '->', ma sono molto scettico riguardo al tipo di argomento 'L':' unit8_t' dovrebbe essere 'size_t'. – chqrlie

0

memset- set byte in memoria

Synopsis-

#include<string.h> 

void * memset (nulli s *, int c, size_t n)

Descrizione-Il memset () La funzione deve copiare c (convertito in un carattere non firmato) in ciascuno dei primi n byte dell'oggetto a cui punta s. Qui per la funzione di cui sopra, il memset() deve restituire il valore s.

+1

In che modo questa risposta aggiunge valore a un post di 4 anni con altre 5 risposte? –

+0

Stavo cercando una risposta e ho avuto modo di conoscere questa definizione da un'altra fonte. Quindi ho pensato che sarebbe stato utile per le altre persone che sono alla ricerca di questo. – Ashit

0

Sto anche cercando - perché utilizzare memset

anche se qui è qualcosa che è accaduto con me.

ho usato strncpy (dest, source, numero di caratteri) e stava ottenendo risultati errati. anche se ero sicuro circa la dimensione della matrice di destinazione.

così quando ho usato memset prima di strncpy - ho ottenuto ottimi risultati per l'output strncpy. indagherò ulteriormente e riferirò.

+0

Ho paura che questa risposta sia completa senza senso: 'strncpy', che dovresti usare mai perché non fa quello che pensi, ** riempie l'array di destinazione in' '\ 0'' dopo la fine del stringa di origine se detta stringa sorgente è più corta della destinazione. Tuttavia, ** ** non termina la destinazione se la stringa di origine è troppo lunga. Usando 'memset' prima che una chiamata a' strncpy' non cambi nulla. È necessario aver passato un valore errato per l'argomento size, ad esempio la lunghezza della stringa di origine, che è un errore comune. – chqrlie

+0

grazie per il commento. possiamo usare strncpy per implementare la routine di sottostringa come di seguito: strncpy (one_char_prod_arr [pcount], token.data.scalar.value, 1); one_char_prod_arr ottiene il primo carattere di token.data.scalar.value –

+0

Vorrei consigliare di non usare 'strncpy' per questo o qualsiasi altro scopo. Puoi usare 'memcpy()' per estrarre una porzione della stringa, ma assicurati di aggiungere manualmente il terminatore null. – chqrlie

Problemi correlati