Namespaces
Variants

memset, memset_explicit, memset_s

From cppreference.net
< c ‎ | string ‎ | byte
Definido en el encabezado <string.h>
void * memset ( void * dest, int ch, size_t count ) ;
(1)
void * memset_explicit ( void * dest, int ch, size_t count ) ;
(2) (desde C23)
errno_t memset_s ( void * dest, rsize_t destsz, int ch, rsize_t count ) ;
(3) (desde C11)
1) Copia el valor ( unsigned char ) ch en cada uno de los primeros count caracteres del objeto apuntado por dest .
El comportamiento es indefinido si el acceso ocurre más allá del final del array dest. El comportamiento es indefinido si dest es un puntero nulo.
2) Igual que (1) , excepto que es seguro para información sensible.
3) Igual que (1) , excepto que los siguientes errores se detectan en tiempo de ejecución y llaman a la función constraint handler actualmente instalada después de almacenar ch en cada ubicación del rango de destino [ dest, dest + destsz ) si dest y destsz son válidos por sí mismos:
  • dest es un puntero nulo
  • destsz o count es mayor que RSIZE_MAX
  • count es mayor que destsz (ocurriría un desbordamiento de búfer)
El comportamiento es indefinido si el tamaño del array de caracteres apuntado por dest < count <= destsz ; en otras palabras, un valor erróneo de destsz no expone el inminente desbordamiento de búfer.
Como con todas las funciones con verificación de límites, memset_s solo está garantizada de estar disponible si __STDC_LIB_EXT1__ está definido por la implementación y si el usuario define __STDC_WANT_LIB_EXT1__ a la constante entera 1 antes de incluir <string.h> .

Contenidos

Parámetros

dest - puntero al objeto a rellenar
ch - byte de relleno
count - número de bytes a rellenar
destsz - tamaño del array de destino

Valor de retorno

1,2) Una copia de dest
3) cero en caso de éxito, distinto de cero en caso de error. También en caso de error, si dest no es un puntero nulo y destsz es válido, escribe destsz bytes de relleno ch en el array de destino.

Notas

memset puede ser optimizado (bajo las reglas as-if ) si el objeto modificado por esta función no se accede nuevamente durante el resto de su tiempo de vida (por ejemplo, gcc bug 8537 ). Por esa razón, esta función no puede usarse para limpiar memoria (por ejemplo, para llenar con ceros un array que almacenó una contraseña).

Esta optimización está prohibida para memset_explicit y memset_s : están garantizados para realizar la escritura de memoria.

Las soluciones de terceros para eso incluyen FreeBSD explicit_bzero o Microsoft SecureZeroMemory .

Ejemplo

#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
}

Salida posible:

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

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 7.24.6.1 La función memset (p: 270)
  • K.3.7.4.1 La función memset_s (p: 451)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 7.24.6.1 La función memset (p: 371)
  • K.3.7.4.1 La función memset_s (p: 621-622)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 7.21.6.1 La función memset (p: 333)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 4.11.6.1 La función memset

Véase también

copia un búfer a otro
(función)
(C95)
copia el carácter ancho dado a cada posición en un arreglo de caracteres anchos
(función)