Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

533
Visualizações
Sobre una mejor comprensión del comportamiento de la función strncpy()

En la página de manual de Linux de strncpy leí:

Si la longitud de src es menor que n, strncpy() escribe
bytes nulos a dest para garantizar que se escriba un total de n bytes.

En este caso límite (sin \0 al final de ambas cadenas) donde n>4:

 char dest[8]="qqqqqqqq"; char src[4] = "abcd"; strncpy(dest, src, 5);

imprimir dest char por char da "abcdqqqq". Como src no tiene \0, no se copia \0 de src a dest, pero si entiendo correctamente la página de manual, se deben copiar otros 4 caracteres en cualquier caso, y deberían ser \0. Además, si src es "abc" (por lo que termina en NUL), dest contiene "abc\0\0qqq". Agrego todo el código que usé para probar (sí, va al carácter 8 para verlo también):

 #include <stdio.h> #include <string.h> int main() { char dest[8]="qqqqqqqq"; char src[4] = "abcd"; // "abc" strncpy(dest, src, 5); for (int i=0; i<9; i++) printf("%2x ", dest[i]); putchar('\n'); return 0; }

¿Es esta una implementación defectuosa o me estoy perdiendo algo?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Si la longitud de src

Ese es el problema, su src no es una cadena terminada en nulo, por lo que strncpy no tiene idea de cuánto tiempo es. La página de manual también tiene un código de muestra que muestra cómo funciona strncpy : se detiene en un byte nulo y, si no encuentra uno, simplemente sigue leyendo hasta que llega a n . Y en su caso, lee los 4 caracteres de src y obtiene el quinto de dest porque es el siguiente en la memoria. (Puede intentar imprimir src[4] , nada lo detendrá y obtendrá la q de dest . ¿No es agradable C?)

over 4 years ago · Santiago Trujillo Relatório

0

Parece que está utilizando strncpy() con un argumento fuente que no es una cadena sino una matriz de caracteres. Entonces, ¿por qué esperas que se comporte con sensatez? El manual de Linux dice claramente que toma una cadena como argumento de origen y que la copia "incluido el byte nulo de terminación" (que supone tal byte). Tenga en cuenta que no existe tal cosa como una "cadena no terminada". Una matriz de caracteres es solo una matriz de caracteres, y no se garantiza que las funciones de cadena funcionen en ella.

Sin embargo, el comportamiento específico que está observando es esperado y está documentado.

La justificación de strncpy() en el estándar POSIX contiene la siguiente oración:

Si no hay un byte de carácter NUL en los primeros n bytes de la matriz a la que apunta s2 , el resultado no termina en nulo.

... donde s2 es lo que llamas src .

El manual de strncpy() en al menos Ubuntu y OpenBSD contiene textos similares.

over 4 years ago · Santiago Trujillo Relatório

0

Veamos esto lógicamente, usando citas de la página del manual de GNU con fecha 2017-09-15, como se incluye en Debian 10:

Si la longitud de src es menor que n , strncpy () escribe bytes nulos adicionales en dest para garantizar que se escriba un total de n bytes.

Como dices correctamente (más o menos), n == 5 . Entonces, ¿cuál es la "longitud de src "? Como todos deberíamos saber, las cadenas C tienen terminación nula. La página del manual sugiere esto:

La función strcpy () copia la cadena a la que apunta src , incluido el byte nulo final ('\0')... La función strncpy () es similar, excepto que se copian como máximo n bytes de src .

Sin embargo, su cadena no termina en nulo. Entonces, después de leer los 4 bytes que definiste, strncpy intenta leer un quinto byte, ¿y qué encuentra? Aparentemente, el primer byte de dest (en realidad, esto depende de la implementación, hasta donde yo sé). Todavía no ha encontrado un nulo para terminar la cadena, entonces, ¿sigue leyendo? No, porque como se dijo anteriormente:

se escriben un total de n bytes

y

se copian como máximo n bytes de src .

Entonces copia los 5 bytes "abcdq" en dest .

Tu dijiste:

los otros 4 caracteres deben copiarse en cualquier caso, y deben ser \0s

Esto implica una longitud total de 8 bytes. ¿De dónde sacarías esto? Esta es la "longitud" (o al menos la longitud declarada de la matriz) de dest , no src , y en cualquier caso se anularía por el hecho de que n < 8 .

El caso en el que src termina en nulo es sencillo.

Así que no, la implementación no es defectuosa .

En realidad, tuviste suerte:

Las cuerdas no pueden superponerse

Lo hacen aquí, así que, técnicamente, cualquier cosa podría pasar. De hecho, un comentario sobre la pregunta dice que Valgrind advierte sobre esto.

y la cadena de destino dest debe ser lo suficientemente grande para recibir la copia. ¡Cuidado con los desbordamientos de búfer!

Este descuido con las longitudes de las cadenas debería ser una advertencia para tener mucho cuidado antes de crear una saturación del búfer.

En otra nota, si bien es posible que una función como strncpy tenga un error, es muy poco probable . Las implementaciones estándar se han probado exhaustivamente en una amplia variedad de entornos. Cualquier error aparente es mucho más probable que sea un error en su propio código, o una falta de comprensión de su propio código, como es el caso aquí.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda