strcpy ... desee reemplazar con strcpy_mine que strncpy y nula por terminado

StackOverflow https://stackoverflow.com/questions/951119

  •  11-09-2019
  •  | 
  •  

Pregunta

la clave está en el título, pero básicamente he heredado algo de código que tiene más de 800 casos de strcpy. Quiero escribir una nueva función y luego a reemplazar strcpy con strcpy_mine.

Así que estoy tratando de averiguar lo que la lista de parámetros strcpy_mine tendrá.

He intentado:

void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
  const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
  strncpy( pTarget, pCopyMe, lenAlwaysFour );

  //add extra terminator in case of overrun
  pTarget[lenAlwaysFour] = 0;
}

pero el sizeof es siempre 4 pCopyMe es un puntero

lo que no quiero hacer es sustituir

strcpy (buf, pCopyMe);

con

strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;

alguna idea? (Strcpy_l no está disponible)

aplausos

¿Fue útil?

Solución

En función de cómo las llamadas sitios parecen, a menudo mayoría de los casos puede ser manejado por una simple plantilla:

#include <string.h>

template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
  strncpy( pTarget, pCopyMe, bufferSize-1 );

  //add extra terminator in case of overrun
  pTarget[bufferSize-1] = 0;
}

int main()
{
  char buf[128];
  strcpy_mine(buf,"Testing");
  return 0;
}

Si está utilizando Microsoft Visual Studio 2005 o más reciente, consulte Las sobrecargas Plantilla seguros para una implementación de Microsoft.

Otros consejos

sizeof () devuelve el tamaño del tipo -. En este caso const char* const que será 4 en máquinas de 32 bits

Creo que piensa que quiere strlen(). Pero esa no es la forma correcta de usar funciones strncpy. Es necesario el tamaño de la salida buffer para strncpy.

Para solucionar este problema es necesario examinar el código en cada sitio de llamadas, y calcular el tamaño del búfer de salida, y pasar eso como un argumento para strcpy_mine. Si la llamada in situ para strcpy (o strcpy_mine) no conoce el tamaño del búfer de salida, es necesario buscar hacia atrás en el código para la ubicación que asigna el búfer, y pasar el tamaño de todo el camino hasta el sitio strcpy .

Básicamente no se puede escribir una gota en el reemplazo para strcpy que toma los mismos argumentos y la esperanza de evitar los problemas que produjeron strncpy en el primer lugar (y mejores reemplazos más allá de eso). Puede crear una función que toma los mismos argumentos strncpy, pero asegura que el resultado es terminada en null - vistazo a la implementación de strlcpy de OpenBSD () función. Pero el primer paso tiene que ser cambiar los sitios de llamadas a transmitir el conocimiento del tamaño del búfer de salida.

Un poco periférica tal vez, pero ya nadie lo mencionó y se hizo alarde en el título:. No puede (legalmente) escribir una función global llamada strcpy_mine()

El "nombre" de funciones cuyos nombres comienzan con str se reserva para la biblioteca estándar. Ver, por ejemplo, la respuesta aceptada a esta cuestión.

Se puede usar la misma lista de parámetros como strncpy para su strcpy_mine, pero escribirlo de manera que siempre nula termina el resultado. No debería ser muy difícil de hacer.

Uno de los retos, sin embargo, es que algunos de su código existente que llama strcpy () no puede saber el tamaño de la memoria intermedia, tampoco.

También puede utilizar macroses para evitar la multiplicidad de ediciones. O automatizar la edición a través de una secuencia de comandos.

Es imprescindible disponer de pasar en el tamaño del búfer de destino como un parámetro, como otras personas han dicho anteriormente.

Esto es un poco fuera de tema, pero sólo quiero señalar que, después de utilizar strncpy(), es necesario configurar para anular el último carácter de la memoria intermedia, que tiene el índice 1 menor que la longitud (no la longitud de la memoria intermedia):

strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';

O, alternativamente, puede utilizar strncat() en una cadena vacía, pasándole una longitud que es menos 1, y garantizará a nulo finalizar su cadena:

buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);

Douglas Leeder tiene razón. Hay un límite a la utilidad de la sustitución de strcpy a menos que esté dispuesto a hacer el trabajo sucio de pasar en una buena, sana longitud de búfer en cada una de las instancias. Eso es un montón de trabajo!

La buena noticia es que vale la pena! Hace unos años atrás, entré en varios proyectos de C ++ que llegaron tarde, con errores, y poco fiable. Al declarar strcpy y strlen prohibido, y tomando 2-3 días fuera del proyecto de sustituirlos por encargo strncpy / strnlen, en todos estos proyectos en los que de repente podía correr durante días en lugar de horas. También vimos una gran cantidad de cadenas truncadas salir la visualización en pantalla y los archivos de registro. Eso nos dio las pistas necesarias para localizar a los problemas de truncamiento, antes de estrellarse problemas.

Si no quieres hacer esto, se puede obtener un beneficio mucho más pequeña, simplemente seleccionando ambos parámetros de puntero NULL, y limitar el tamaño máximo de una copia de cadena y registrar todas las veces que se ha alcanzado el límite. no hacer un strlen de cualquiera de los parámetros, como strlen estará feliz de estrellarse en que si la cadena no está correctamente terminada en nulo.

Hoy en día, los nuevos proyectos utilizan buenos objetos de cadena, pero hay una gran cantidad de código heredado por ahí que no lo hace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top