Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

391
Vistas
El uso de strerror() dos veces con diferentes valores dentro de un printf() desencadena un error en Windows

De acuerdo con los documentos de Microsoft, la API char * strerror(int errnum)

"asigna errnum a una cadena de mensaje de error y devuelve un puntero a la cadena"

En la práctica resultó que hay un aspecto importante que no está cubierto por la descripción:

  • En Windows se usa el mismo puntero para diferentes valores de errnum. Causó un comportamiento inesperado: strerror() con diferente errnum en un printf() ¡muestra el mismo valor !

Este es el código que representa este comportamiento:

 printf("---------- print separately [OK] ----------\n"); printf("strerror(1)=(%s), ptr=(%p)\n", strerror(1), strerror(1)); printf("strerror(2)=(%s), ptr=(%p)\n", strerror(2), strerror(2)); printf("---------- print together [BUG] ----------\n"); printf("strerror(1)=(%s), strerror(2)=(%s)\n", strerror(1), strerror(2)); printf("ptr_1=(%p), ptr_2=(%p)\n", strerror(1), strerror(2)); printf("---------- print together, get pointers separately [BUG] ----------\n"); const char * s1 = strerror(1); const char * s2 = strerror(2); printf("strerror(1)=(%s), strerror(2)=(%s)\n", s1, s2); printf("ptr_1=(%p), ptr_2=(%p)\n", s1, s2); printf("---------- --------------------------- ----------\n");

Producción:

 ---------- print separately [OK] ---------- strerror(1)=(Operation not permitted), ptr=(000002756DE6BD90) strerror(2)=(No such file or directory), ptr=(000002756DE6BD90) ---------- print together [BUG] ---------- strerror(1)=(Operation not permitted), strerror(2)=(Operation not permitted) ptr_1=(000002756DE6BD90), ptr_2=(000002756DE6BD90) ---------- print together, get pointers separately [BUG] ---------- strerror(1)=(No such file or directory), strerror(2)=(No such file or directory) ptr_1=(000002756DE6BD90), ptr_2=(000002756DE6BD90) ---------- --------------------------- ----------

No se usaron banderas de optimización del compilador. El mismo código funciona correctamente en Linux con gcc.

ACTUALIZACIÓN: Las preguntas están respondidas.

P: ¿Este comportamiento es un ERROR?

  • NO.

P: ¿Existe otra API mejor que funcione como strerror en Linux?

  • SÍ. strerror_s.
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

La memoria devuelta por strerror se puede modificar mediante llamadas posteriores a la función.

En su lugar, use strerror_s que le permite proporcionar un búfer para escribir la cadena de error.

 char s1[200], s2[200]; strerror_s(s1, sizeof s1, 1); strerror_s(s2, sizeof s2, 2);
over 4 years ago · Santiago Trujillo Denunciar

0

Esto no es un error. Según la documentación de POSIX para strerror:

El puntero de cadena devuelto podría invalidarse o el contenido de la cadena podría sobrescribirse con una llamada posterior a strerror()

Entonces, si lo llama dos veces en una sola declaración, no debe esperar que más de uno de los valores sea válido (y sería perfectamente aceptable que su código se bloquee o haga otras cosas extrañas).

La razón subyacente probablemente se deba a que la biblioteca de Microsoft C utiliza un solo búfer fijo para el valor de retorno de strerror , por lo que cada llamada sobrescribe el valor retenido anterior. Esto está específicamente permitido por el estándar, para facilitar la implementación.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda