Namespaces
Variants

memset, memset_explicit, memset_s

From cppreference.net
< c ‎ | string ‎ | byte
Definiert in Header <string.h>
void * memset ( void * dest, int ch, size_t count ) ;
(1)
void * memset_explicit ( void * dest, int ch, size_t count ) ;
(2) (seit C23)
errno_t memset_s ( void * dest, rsize_t destsz, int ch, rsize_t count ) ;
(3) (seit C11)
1) Kopiert den Wert ( unsigned char ) ch in jedes der ersten count Zeichen des Objekts, auf das dest zeigt.
Das Verhalten ist undefiniert, wenn der Zugriff über das Ende des dest-Arrays hinaus erfolgt. Das Verhalten ist undefiniert, wenn dest ein Nullzeiger ist.
2) Gleich wie (1) , außer dass es für sensible Informationen sicher ist.
3) Gleich wie (1) , mit der Ausnahme, dass die folgenden Fehler zur Laufzeit erkannt werden und die aktuell installierte Constraint-Handler-Funktion aufrufen, nachdem ch an jeder Position des Zielbereichs [ dest, dest + destsz ) gespeichert wurde, falls dest und destsz selbst gültig sind:
  • dest ist ein Nullzeiger
  • destsz oder count ist größer als RSIZE_MAX
  • count ist größer als destsz (Pufferüberlauf würde auftreten)
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das dest zeigt, < count <= destsz ; mit anderen Worten, ein fehlerhafter Wert von destsz macht den drohenden Pufferüberlauf nicht offensichtlich.
Wie bei allen grenzprüfenden Funktionen ist memset_s nur garantiert verfügbar, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ auf den Integer-Konstantenwert 1 setzt, bevor <string.h> eingebunden wird.

Inhaltsverzeichnis

Parameter

dest - Zeiger auf das zu füllende Objekt
ch - Füllbyte
count - Anzahl der zu füllenden Bytes
destsz - Größe des Zielarrays

Rückgabewert

1,2) Eine Kopie von dest
3) Null bei Erfolg, ungleich Null bei Fehler. Bei Fehler wird, falls dest kein Nullzeiger ist und destsz gültig ist, destsz Füllbytes ch in das Zielarray geschrieben.

Hinweise

memset kann wegoptimiert werden (gemäß den as-if Regeln), wenn auf das von dieser Funktion modifizierte Objekt für den Rest seiner Lebensdauer nicht mehr zugegriffen wird (z.B. gcc bug 8537 ). Aus diesem Grund kann diese Funktion nicht zum Überschreiben von Speicher verwendet werden (z.B. um ein Array, das ein Passwort gespeichert hat, mit Nullen zu füllen).

Diese Optimierung ist für memset_explicit und memset_s verboten: Sie garantieren die Ausführung des Speicherschreibvorgangs.

Drittanbieter-Lösungen dafür beinhalten FreeBSD explicit_bzero oder Microsoft SecureZeroMemory .

Beispiel

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    char str[] = "ghghghghghghghghghghgh";
    puts(str);
    memset(str,'a',5);
    puts(str);
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = memset_s(str, sizeof str, 'b', 5);
    printf("str = \"%s\", r = %d\n", str, r);
    r = memset_s(str, 5, 'c', 10);   // count is greater than destsz  
    printf("str = \"%s\", r = %d\n", str, r);
#endif
}

Mögliche Ausgabe:

ghghghghghghghghghghgh
aaaaahghghghghghghghgh
str = "bbbbbhghghghghghghghgh", r = 0
str = "ccccchghghghghghghghgh", r = 22

Referenzen

  • C17 Standard (ISO/IEC 9899:2018):
  • 7.24.6.1 Die memset-Funktion (S. 270)
  • K.3.7.4.1 Die memset_s-Funktion (S. 451)
  • C11 Standard (ISO/IEC 9899:2011):
  • 7.24.6.1 Die memset-Funktion (S. 371)
  • K.3.7.4.1 Die memset_s-Funktion (S. 621-622)
  • C99-Standard (ISO/IEC 9899:1999):
  • 7.21.6.1 Die memset-Funktion (S. 333)
  • C89/C90-Standard (ISO/IEC 9899:1990):
  • 4.11.6.1 Die memset-Funktion

Siehe auch

kopiert einen Puffer in einen anderen
(Funktion)
(C95)
kopiert das gegebene Breitzeichen an jede Position in einem Breitzeichen-Array
(Funktion)