memset în C

Umple primii n octeți ai unei zone de memorie cu aceeași valoare, de obicei 0.

Sintaxă
#include <string.h>
void *memset(void *s, int c, size_t n);

Ce face memset

memset(s, c, n) scrie valoarea c (convertită la unsigned char) în fiecare din cei n octeți. Se folosește mai ales pentru a pune pe zero un tablou sau o structură: memset(&x, 0, sizeof x).

Lucrează pe octeți, nu pe elemente. memset cu 0 dă zero pentru orice tip întreg, dar memset(tablou_int, 1, ...) nu pune 1 în fiecare int, ci octetul 1 în fiecare din cei 4 octeți: valoarea devine 16843009 (0x01010101).

Pentru o variabilă locală nouă, inițializarea int v[10] = {0}; sau, în C23, int v[10] = {}; face același lucru mai clar.

Parametri

Parametru Descriere
s Începutul zonei.
c Valoarea octetului scris (0–255).
n Câți octeți se scriu.

Ce returnează

Pointerul s.

Exemple

Exemplul 1: Resetarea unui tablou de contoare

#include <stdio.h>
#include <string.h>

int main(void) {
    int voturi[4] = {12, 7, 3, 9};
    memset(voturi, 0, sizeof voturi);
    for (size_t i = 0; i < 4; i++) {
        printf("%d ", voturi[i]);
    }
    printf("\n");
    return 0;
}

Rezultat

0 0 0 0

Exemplul 2: Capcana: memset cu 1 pe un int

#include <stdio.h>
#include <string.h>

int main(void) {
    int x;
    memset(&x, 1, sizeof x);
    printf("x = %d (0x%08x)\n", x, (unsigned)x);
    return 0;
}

Rezultat

x = 16843009 (0x01010101)

Exemplul 3: Un rând de liniuță pentru tabel

#include <stdio.h>
#include <string.h>

int main(void) {
    char linie[21];
    memset(linie, '-', 20);
    linie[20] = '\0';
    printf("%s\nProdus       Preț\n%s\n", linie, linie);
    return 0;
}

Rezultat

--------------------
Produs       Preț
--------------------

Greșeli frecvente

  • Pui argumentele în ordine greșită: memset(v, sizeof v, 0) nu scrie nimic (n = 0). Ordinea este zonă, valoare, număr de octeți.
  • Folosești sizeof p pe un pointer la memorie alocată: dă mărimea pointerului (8), nu a zonei.
  • Pui pe zero o zonă cu date secrete înainte de free: compilatorul poate elimina un memset pe memorie care nu mai este citită. C23 are pentru asta memset_explicit.

Comenzi înrudite

  • memcpy: Copiază n octeți dintr-o zonă de memorie în alta; zonele nu au voie să se suprapună.
  • calloc: Alocă memorie pentru un tablou de count elemente a câte size octeți și pune zero în toți octeții.
  • Tablouri (array): Un șir de elemente de același tip, așezate unul după altul în memorie și accesate prin index, de la 0.
  • sizeof: Operatorul care spune câți octeți ocupă un tip sau o variabilă; calculat de compilator, rezultatul are tipul size_t.