Pregunta strncpy o strlcpy en mi caso


que debería usar cuando quiero copiar src_str a dst_arr ¿y por qué?

char dst_arr[10];
char *src_str = "hello";

PD: mi cabeza está girando más rápido que el disco de mi computadora después de leer muchas cosas sobre cómo bueno o malo es strncpy y strlcpy.

Nota: sé strlcpy no está disponible en todas partes. Esa no es la preocupación aquí.


9
2017-08-08 19:04


origen


Respuestas:


strncpy es Nunca la respuesta correcta cuando tu cadena de destino termina en cero. strncpy es una función destinada a ser utilizada sin terminación ancho fijo instrumentos de cuerda. Más precisamente, su propósito es convertir una cadena terminada en cero en una cadena de ancho fijo no terminada (mediante copia). En otras palabras, strncpy no es significativamente aplicable aquí.

La verdadera elección que tienes aquí es entre strlcpy y simple strcpy.

Cuando desee realizar una copia "segura" (es decir, potencialmente truncada) en dst_arr, la función adecuada para usar es strlcpy.

Como para dst_ptr... No existe tal cosa como "copiar a dst_ptr". Puedes copiar a memoria apuntado por dst_ptr, pero primero debes asegurarte de que apunta a algún lugar y asignar esa memoria. Hay muchas formas diferentes de hacerlo.

Por ejemplo, puedes hacer dst_ptr apuntar a dst_arr, en cuyo caso la respuesta es la misma que en el caso anterior - strlcpy.

O puede asignar la memoria usando malloc. Si se garantiza que la cantidad de memoria asignada será suficiente para la cadena (es decir, al menos strlen(src_str) + 1 bytes está asignado), entonces puede usar el plano strcpy o incluso memcpy para copiar la cadena No hay necesidad ni razón para usar strlcpy en este caso, aunque algunas personas podrían preferir usarlo, ya que de alguna manera les da la sensación de mayor seguridad.

Si intencionalmente asigna menos memoria (es decir, desea que su cadena se trunque), entonces strlcpy se convierte en la función correcta para usar.


23
2017-08-08 19:07



strlcpy() es mas seguro que strncpy() así que bien podrías usarlo.
Los sistemas que no lo tienen a menudo tendrán una s_strncpy() eso hace lo mismo

Nota : no puedes copiar nada a dst_ptr hasta que apunta a algo


5
2017-08-08 19:06



No sabía de strlcpy. Acabo de encontrar aquí ese:

Las funciones strlcpy () y strlcat () copian y concatenan cadenas   respectivamente. Están diseñados para ser más seguros, más consistentes y   menos reemplazos propensos a errores para strncpy (3) y strncat (3).

Así que strlcpy costuras más seguras.

Editar: Una discusión completa está disponible aquí.

Edit2:

Me doy cuenta de que lo que escribí anteriormente no responde a la parte "en su caso" de su pregunta. Si tu entender las limitaciones de strncpy, supongo que puedes usarlo y escribir un buen código para evitar sus trampas; pero si no está seguro de que comprende sus límites, use strlcpy.

Mi comprensión de las limitaciones de strncpy y strlcpy es que puedes hacer algo muy malo con strncpy (desbordamiento de buffer), y lo peor que puedes hacer con strlcpy es perder un char en el proceso.


2
2017-08-08 19:09



Deberías usar siempre la función estándar, que en este caso es el C11 strcpy_s() función. No strncpy(), ya que no es seguro, no garantiza la terminación cero. Y no solo en OpenBSD strlcpy(), ya que también es inseguro, y OpenBSD siempre produce sus propios inventos, que generalmente no lo convierten en ningún estándar.

Ver http://en.cppreference.com/w/c/string/byte/strcpy

La función strcpy_s es similar a la función BSD strlcpy, excepto que strlcpy trunca la cadena fuente para encajar en el destino (que es un riesgo de seguridad)

  • strlcpy no realiza todas las comprobaciones de tiempo de ejecución que strcpy_s hace
  • strlcpy no hace las fallas obvias al establecer el destino en una cadena nula o llamar a un controlador si la llamada falla.
  • Aunque strcpy_s prohíbe el truncamiento debido a posibles riesgos de seguridad, es posible truncar una cadena utilizando strncpy_s en lugar de limit-checked.

Si su biblioteca C no tiene strcpy_s, usa la lib segura. https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html


1
2017-11-16 00:35



En primer lugar, su dst_ptr no tiene espacio asignado y no lo ha configurado para que apunte a los demás, por lo que asignarle algo probablemente causaría un error de segmentación.

Strncpy debería funcionar perfectamente bien, solo haz lo siguiente:

strncpy(dst_arr, src_str, sizeof(dst_arr));

y sabes que no se desbordará dst_arr. Si usa un src_str más grande, puede que tenga que poner su propio terminador nulo al final de dst_arr, pero en este caso su fuente es <su destino, por lo que se rellenará con valores nulos de todos modos.

Esto funciona en todas partes y es seguro, por lo que no miraría nada más a menos que su curiosidad intelectual.

También tenga en cuenta que sería bueno usar un número que no sea mágico para el 10, para que sepa el tamaño de que coincida con el tamaño del strncpy :)


-1
2017-08-08 19:11



no deberías usar strncpy y no strlcpy para esto. Mejor usas

*dst_arr=0; strncat(dst_arr,src_arr,(sizeof dst_arr)-1);

o sin una inicialización

sprintf(dst_arr,"%.*s",(sizeof dst_arr)-1,src_arr);

dst_arr aquí debe ser una matriz NO un puntero.


-1
2017-08-08 20:17