2010-07-09 11 views
5

En programación C, siempre que intente realizar primer gato tiempo, necesitoEstablecer el primer byte a 0 o uso memset a "reset" todo el búfer

TCHAR file_name[1024]; 
// Use memset or set the first byte to 0? 
file_name[0] = 0; 
_tcscat(file_name, TEMP_DIRECTORY_PATH); 
_tcscat(file_name, file); 

veo la mayoría de los programadores están utilizando memset. Pero, para mí, simplemente configuro el primer byte en 0, para que _tcscat sepa por dónde empezar.

No estoy seguro de si hay algún defecto/trampa para hacerlo, en lugar de usar memset?

Gracias.

Respuesta

3

Usted puede acaba de establecer el primer char a 0.

Sin embargo una manera más fácil sería

TCHAR file_name[1024]; 
_tcsncpy(file_name, TEMP_DIRECTORY_PATH, 1024); 
_tcscat(file_name, file); 
1

Ninguno realmente, aparte de que establecer todo en nulos puede evitar errores más adelante, es decir, si no agrega uno por algún motivo. Es más fácil llenar toda la cadena con ceros y saber que no tiene que preocuparse por agregar manualmente un terminador nulo más adelante siempre que no desborde el búfer.

+0

No estoy de acuerdo. Es más probable que oculte errores en la lógica que aparecerá repentinamente cuando alguien que mantiene el código más tarde decida "¡vamos a eliminar todos estos memsets inútiles!" –

1

Configurar toda la memoria intermedia a los caracteres NUL es una "defensa en profundidad". Tal defensa cubre un error cometido en otra parte del código fuente, tal vez por un programador diferente. En este caso, el error protegido sería copiar una cadena que se ajusta al buffer, pero no copiar el byte de terminación NUL. El búfer que ya tenía cero proporcionaría NUL de terminación para esta copia de cadena errónea a "usar". Los programadores difieren en la sabiduría de "Defensa en profundidad" porque dicha codificación puede enmascarar errores de programación que luego se pueden infectar en el código fuente, y que se solucionan solo después de que se introducen.

En mi opinión personal, establecer el búfer para todos los caracteres NUL como esto como una "defensa en profundidad" es una gran pérdida. Tendría más sentido solo NUL el byte final. Entonces los errores se mostrarían pero las cadenas eventualmente terminarían. Una vez que empiezas a ir por ese camino del pensamiento, la "defensa en profundidad" tendría más sentido si el búfer estuviera compuesto por dos palabras de máquina más largas, y esas palabras fueran cero, y posiblemente un valor canario podría informar un desbordamiento del buffer, y ....

O simplemente no podría desbordar los búferes, y escribir su programa para que se bloquee lo más rápido posible si lo hace. Eso es lo que me gusta hacer.

+0

+1 para un buen análisis de los pros y los contras de las diferentes opciones. –

4

no estoy de acuerdo con la mayoría de las respuestas que parecen indicar que la fijación de la totalidad el buffer a 0 puede ser útil. Si está copiando/concatenando cadenas terminadas en nulo en el búfer, no hay necesidad de aclarar todo, me parece que es un desperdicio (aunque ciertamente podría ser un desperdicio del que no vale la pena preocuparse).

Es posible que tome el enfoque que Artelius suggested y utilizar una variante strcpy() para obtener la cadena inicial en el búfer, pero creo que la simetría de su enfoque usando strcat() `tiene mérito también (aunque creo que sólo la creación el primer carácter a 0 es suficiente).

Como un aparte, si el búfer puede contener datos 'sensibles' (información de contraseña o algo así) - esa podría ser una razón para borrar todo. Pero si ese es el caso, eche un vistazo a http://msdn.microsoft.com/en-us/library/ms972826 por algunas razones por las cuales memset() podría no ser suficiente.

+0

¿De verdad? Creo que es bastante estúpido configurar el búfer en ceros, pero creo que eso no apareció en mi respuesta. –

+0

Y hagas lo que hagas para memoria segura cero, no la guarde en el almacenamiento protegido de Microsoft ... Eso es compatible con CALEA, obviamente. Elija su lado, supongo. –

+0

Si quiere simetría, puede usar 'strcpy (s," "); 'para" inicializar "la cadena y aún usar' strcat' para todas las escrituras apropiadas. –

Cuestiones relacionadas