Asumo su interés surge principalmente de una perspectiva del rendimiento, ya que las soluciones como vector, cadena, cadena de caracteres, etc. generalmente funcionarán incluso para interactuar con las API de C. Recomiendo aprender cómo usarlos y cómo usarlos de manera eficiente. Si realmente lo necesita, puede incluso escribir su propio asignador de memoria para que sea súper rápido. Si está seguro de que no es lo que necesita, no hay excusa para no escribir un envoltorio simple para manejar estos almacenamientos intermedios de cadena con RAII para los casos dinámicos.
Con eso fuera del camino:
está pasando el búfer como & buffer [0] mejor estilo de programación de pasar búfer? (Prefiero & buffer [0].)
No. Me parece que es el estilo que sea un poco menos útil (por ser incontestablemente subjetiva aquí) ya que no se puede utilizar para pasar una memoria intermedia nula y por lo tanto tendría que hacer excepciones a su estilo para pasar punteros a matrices que pueden ser nulas. Sin embargo, es necesario si transfiere datos de std :: vector a una API de C esperando un puntero.
¿Hay un tamaño máximo que se considera seguro para pila asignado tampones?
Esto depende de la plataforma y la configuración del compilador. Regla general: si tiene dudas sobre si su código se desbordará en la pila, escríbalo de una manera que no pueda.
Es un búfer estático (carga estática búfer [N];) ¿más rápido? ¿Hay algún otro argumento a favor o en contra del ?
Sí, hay un gran argumento en contra, y es que hace que su función ya no vuelva a entrar. Si su aplicación se convierte en multiproceso, estas funciones no serán seguras para subprocesos. Incluso en una aplicación de subproceso único, compartir el mismo búfer cuando estas funciones son llamadas recursivamente puede ocasionar problemas.
¿Qué pasa con el uso del búfer de char * estático = new char [N]; y nunca borrar el buffer? (Reutilizando el mismo buffer cada llamada a )
Todavía tenemos los mismos problemas de reentrada.
entiendo que asignación de montón se debe utilizar cuando (1) se trata de grandes tampones o (2) de tamaño máximo de memoria intermedia es desconocida en tiempo de compilación. ¿Hay algún otro factor que juegue en la decisión de asignación de pila/montón?
El desenrollado de la pila destruye los objetos de la pila. Esto es especialmente importante para la seguridad de excepciones. Por lo tanto, incluso si asigna memoria en el montón dentro de una función, generalmente debe ser administrado por un objeto en la pila (por ejemplo: puntero inteligente). /// @ ver RAII.
¿Prefiere sprintf_s, memcpy_s, ... variantes? (Visual Studio ha estado tratando de convencerme de esta durante mucho tiempo, pero yo quiero una segunda opinión : p)
MS tenía razón acerca de estas funciones son alternativas más seguras, ya que no tienen memoria intermedia problemas de desbordamiento, pero si escribe tal código tal como está (sin variantes de escritura para otras plataformas), su código estará casado con Microsoft, ya que no será portátil.
Al usar memorias intermedias estáticas puede usar tipo de retorno const char *. ¿Es esto (generalmente) una buena o una mala idea? (I doy cuenta de que la persona que llama deberá para hacer su propia copia para evitar que el siguiente llamada que cambiaría el valor anterior retorno.)
yo diría que en casi todos los casos, usted quiere utilice const char * para los tipos de retorno para una función que devuelve un puntero a un búfer de caracteres.Para que una función devuelva un carácter * mutable, generalmente es confuso y problemático. O bien está devolviendo una dirección a datos globales/estáticos que no debería estar usando en primer lugar (ver reentrada arriba), datos locales de una clase (si es un método) en cuyo caso devolverlos arruina la capacidad de la clase para mantener invariantes permitiendo a los clientes manipularlo como quieran (ej: la cadena almacenada siempre debe ser válida), o devolver la memoria que fue especificada por un puntero pasado a la función (el único caso en el que razonablemente podría argumentarse que ese carácter mutable * debe ser devuelto).
¿Qué pasa con boost :: filesystem? –
Olvidó un par de líneas: 'userName.resize (1024, 'A'); userName.insert (0, "world of buffer overflows!"); ' – bk1e