Pregunta

¿Hay alguna llamada que pueda hacer? new para tenerlo a cero de la memoria como calloc?

¿Fue útil?

Solución

Al contrario de lo que algunos dicen en sus respuestas, es posible .

char * c = new char[N]();

Inicializará cero todos los caracteres (en realidad, se llama inicialización de valor. Pero la inicialización de valor será inicialización cero para todos sus miembros de una matriz de tipo escalar). Si eso es lo que buscas.

Vale la pena señalar que también funciona para (matrices de) tipos de clase sin constructor declarado por el usuario, en cuyo caso cualquier miembro de ellos tiene un valor inicializado:

struct T { int a; };
T *t = new T[1]();
assert(t[0].a == 0);
delete[] t;

No es una extensión o algo así. Funcionó y se comportó de la misma manera en C ++ 98 también. Justo allí se llamaba inicialización predeterminada en lugar de inicialización de valor. Sin embargo, la inicialización cero se realiza en ambos casos para escalares o matrices de tipos escalares o POD.

Otros consejos

No, pero es bastante fácil crear una nueva versión que funcione como calloc. Se puede hacer de la misma manera que se implementa la versión sin lanzamiento de new.

SomeFile.h

struct zeromemory_t{};
extern const zeromemory_t zeromemory;
void* __cdcel operator new(size_t cbSize, const zeromemory_t&);

SomeFile.cpp

const zeromemory_t zeromemory;

void* _cdecl operator new(size_t cbSize, const zeromemory_t&)
{
    void *mem = ::operator new(cbSize);
    memset(mem,0,cbSize);
    return mem;
}

Ahora puede hacer lo siguiente para actualizarse con cero memoria

MyType* pMyType = new (zeromemory) MyType();

Además, necesitaría hacer otras cosas divertidas como definir new [], que también es bastante sencillo.

No. Tampoco pienses en hacer algo como:

YourClass *var = new YourClass;
memset(var, 0, sizeof(YourClass));

Podrías terminar destrozando tu VTABLE (si tu clase tiene uno).

Recomendaría usar constructores para borrar la memoria interna (variables) de su clase.

No. Siempre inicializará por defecto los elementos asignados, que en el caso de las primitivas no hace nada. Tendrá que seguir con una llamada std :: uninitialized_fill_n o similar.

Podrías hacer una sobrecarga global de operador. new y hacer que tome la memoria sin procesar de calloc().De esta manera, la memoria se borra antes de que se ejecuten los constructores, por lo que no hay problemas.

Cualquier clase que anule la nueva por sí sola no obtendrá su especial calloc()-basado new, pero esa clase debería inicializarse correctamente de todos modos.

No olvides anular ambos new y delete y las versiones de matriz...

Algo como:

#include <exception> // for std::bad_alloc
#include <new>
#include <stdlib.h> // for calloc() and free()

void* operator new (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc(); 
 return p;
}


void operator delete (void *p)
{
 free(p); 
}

void* operator new[] (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc();
 return p;
}

void operator delete[] (void *p)
{
 free(p); 
}

Tenga en cuenta que estas versiones simples no son exactamente lo que deberían ser: new El operador debe ejecutarse en un bucle llamando al new_handler (si hay uno instalado) y tirando solo el bad_alloc excepción si no hay new_handler.O algo así, tendré que buscarlo y actualizarlo más tarde.

Ah, y es posible que desees anular también el no_throw versión también.

yo uso una macro:

#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE();

para usarlo:

Whatever* myWhatever = newclear(Whatever);

(esto usa " ubicación nueva " como algunas otras soluciones aquí)

No. Debe poner a cero manualmente la memoria. Recuerde, new no se trata solo de asignar memoria, sino también de inicializar mediante constructores. Aquí es donde calloc es útil en C (que no tiene funciones de inicializador). Puede escribir un contenedor sobre <=> o incluso usar <=>, pero la mayoría de las veces para objetos que no son POD esto no tiene mucho sentido.

si no insistes en usar new, simplemente puedes usar el vector: vector<char> buffer; buffer.resize(newsize); y el contenido se pondrá a cero.

class MyClass {
    public:
    void* operator new(size_t bytes) {
        return calloc(bytes, 1);
    }
}

Y puede anular el nuevo operador global si lo desea.

Puedes decir:

vector <char> v( 100, 0 );

que crea una matriz contigua de 100 caracteres usando new, y los inicializa a cero. Luego puede acceder a la matriz con el operador [] del vector, o haciendo:

char * p = &v[0];
p[3] = 42;

Tenga en cuenta que esto también le libera de tener que llamar a borrar para liberar la memoria asignada.

int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5

Para las matrices, puede usar algo como memset. Para Windows use ZeroMemory o SecureZeroMemory.

Editar: Consulte la publicación de @ litb, muestra cómo puede inicializar a 0 para las matrices utilizando una inicialización no directa como se muestra arriba.

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