2010-05-05 44 views
6

Hola chicos. Estoy trabajando en arreglar el código anterior para mi trabajo. Actualmente está escrito en C++. Convirtieron la asignación estática en dinámica pero no editaron las memsets/memcmp/memcpy. Esta es mi primera pasantía de programación tan simple con mi pregunta newbe.Usando memset en estructuras en C++

El siguiente código está en C, pero quiero tenerlo en C++ (he leído que malloc no es una buena práctica en C++). Tengo dos escenarios: Primero, tenemos f creado. Luego usa & f para completar con cero. El segundo es un puntero * pf. No estoy seguro de cómo establecer pf a todos los 0 como el ejemplo anterior en C++.

¿Podría simplemente hacer pf = new foo en lugar de malloc y luego llamar al memset(pf, 0, sizeof(foo))?

struct foo { ... } f; 
memset(&f, 0, sizeof(f)); 

//or 

struct foo { ... } *pf; 
pf = (struct foo*) malloc(sizeof(*pf)); 
memset(pf, 0, sizeof(*pf)); 
+1

Depende de lo que hay en foo! –

Respuesta

8

Sí, pero solo si foo es un POD. Si tiene funciones virtuales o cualquier cosa remotamente C++ ish, no use memset ya que pisará todo el interior de la estructura/clase.

Lo que probablemente quiera hacer en lugar de memset es darle a un constructor para inicializar explícitamente sus miembros.

Si desea utilizar una versión nueva, no olvide la eliminación correspondiente. Aún mejor sería utilizar shared_ptr :)

+0

Gracias Ben. Después de mirar algunos otros archivos que tienen, noté que están usando la nueva forma de inicialización más que crear un constructor para la estructura. Voy a ir con eso ya que no tienen funciones virtuales.Gracias por la ayuda. – garry

+0

@garry: cuando se usa 'new', el constructor todavía se llama. Puedes inicializar sus atributos allí. –

+3

pedantería menor que tanto en C como en C++, incluso con los tipos de POD es un comportamiento técnicamente indefinido simplemente usar 'memset' para borrar la memoria, y luego leer esa memoria como cualquier cosa que no sea' char' y garantizar-no-padding -bits '(u) intN_t' tipos. En la práctica, su implementación dispondrá que todo-0-bytes signifique un puntero nulo, un flotante de 0.0 (como en IEEE754), y así sucesivamente, pero históricamente no todas las implementaciones siempre lo han hecho. –

2

Sí, eso funcionaría. Sin embargo, no creo que malloc sea necesariamente una mala práctica, y no lo cambiaría solo para cambiarlo. Por supuesto, debe asegurarse de que siempre coincida con los mecanismos de asignación correctamente (nuevo-> eliminar, malloc-> libre, etc.).

También podría agregar un constructor a la estructura y usar eso para inicializar los campos.

3

¿Puede usted? Si probablemente. ¿Deberías? No.

Si bien es probable que funcione, está perdiendo el estado que el constructor ha creado para usted. Agregando a esto, ¿qué sucede cuando decides implementar una subclase de esta estructura? Entonces pierde la ventaja del código reutilizable que ofrece C++ OOP.

Lo que debe hacer en su lugar es crear un constructor que inicialice los miembros por usted. De esta manera, cuando sublimes esta estructura más adelante en la línea, simplemente usas este constructor para ayudarte a construir las subclases. ¡Este es un código gratis y seguro! usarlo!

Editar: La advertencia de esto es que si ya tiene una gran base de código, no la cambie hasta que comience a subclasificar las estructuras. Funciona como lo es ahora.

2

Usted podría nueva foo (como es la forma estándar en C++) e implementar un constructor inicializa el que foo en lugar de utilizar memset.

E.g.

struct Something 
{ 
    Something() 
     : m_nInt(5) 
    { 

    } 

    int m_nInt; 
}; 

Tampoco se olvide de si utiliza nueva llamar eliminar cuando haya terminado con el objeto de lo contrario va a terminar con pérdidas de memoria.