Was ist der Nutzen der Funktion memset()
?.
Definition : Setzt die ersten num Bytes des Speicherblocks, auf den ptr zeigt, auf. spezifizierter Wert (interpretiert als vorzeichenloses Zeichen).
Bedeutet das, dass ein Wert in einer Speicheradresse hart codiert wird?
memset(&serv_addr,0,sizeof(serv_addr)
ist das Beispiel, das ich zu verstehen versuche.
Kann jemand bitte sehr vereinfacht erklären?
memset()
ist eine sehr schnelle Version einer relativ einfachen Operation:
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;
}
Das heißt, memset(b, c, l)
setzt die l
Bytes ab Adresse b
auf den Wert c
. Es geht einfach viel schneller als bei der obigen Implementierung.
memset()
wird normalerweise zum Initialisieren von Werten verwendet. Betrachten Sie zum Beispiel die folgende Struktur:
struct Size {
int width;
int height;
}
Wenn Sie eine davon wie folgt auf dem Stapel erstellen:
struct Size someSize;
Dann werden die Werte in dieser Struktur undefiniert. Sie können Null sein, sie können die Werte sein, die zufällig dort waren, als der Teil des Stacks zuletzt verwendet wurde. Normalerweise folgt man dieser Zeile mit:
memset(&someSize, 0, sizeof(someSize));
Natürlich kann es auch für andere Szenarien verwendet werden, dies ist nur eines davon. Stellen Sie sich einfach einen Weg vor, um einen Teil des Speichers auf einen bestimmten Wert zu setzen.
memset
ist eine gängige Methode, um einen Speicherbereich unabhängig vom Datentyp auf 0 zu setzen. Man kann sagen, dass memset
sich nicht für den Datentyp interessiert und nur alle Bytes auf Null setzt.
IMHO in C++ sollte möglichst memset
vermieden werden, da hierdurch die Typensicherheit von C++ umgangen wird. Stattdessen sollte der Konstruktor oder die Initialisierung als Mittel zur Initialisierung verwendet werden. Memset, das für eine Klasseninstanz erstellt wurde, kann auch unbeabsichtigt etwas zerstören:
z.B.
class A
{
public:
shared_ptr<char*> _p;
};
eine Variable memset
in einer Instanz des Obigen würde eine Referenzzählerabnahme nicht ordnungsgemäß durchführen.
Ich denke, dass serv_addr
eine lokale oder globale Variable eines struct
-Typs ist - vielleicht struct sockaddr
- (oder möglicherweise eine class
).
&serv_addr
übernimmt die Adresse dieser Variablen. Es ist eine gültige Adresse, die als erstes Argument an memset
übergeben wird. Das zweite Argument für memset
ist das Byte, das zum Füllen verwendet wird (null Byte). Das letzte Argument für memset
ist die Größe der zu füllenden Speicherzone in Bytes. Dies ist die Größe der serv_addr
-Variablen in Ihrem Beispiel.
Dieser Aufruf von memset
löscht also eine globale oder lokale Variable serv_addr
, die einige struct
enthält.
In der Praxis wird derGCCCompiler, wenn er optimiert wird, einen intelligenten Code dafür generieren, der normalerweise abgerollt und inliniert wird (eigentlich ist es oft ein eingebauter, so dassGCCsehr generieren kann kluger Code dafür).
Es ist nichts anderes, als den Speicher auf einen bestimmten Wert zu setzen.
Hier ist Beispielcode.
Memset (const * p, unit8_t V, unit8_t L), Hier ist P der Zeiger auf den Zielspeicher, V ist der Wert für den Zielpuffer, der auf einen Wert V gesetzt wird und l ist die Länge der Daten.
while(L --> 0)
{
*p++ = V;
}
memset-Bytes im Speicher
Zusammenfassung-
#include<string.h>
void * memset (void * s, int c, size_t n)
Description- Die Funktion memset () kopiert c (in ein unsigniertes Zeichen konvertiert) in jedes der ersten n Bytes des Objekts, auf das mit s verwiesen wird. Hier wird für die obige Funktion der Wert von memset () zurückgegeben.