Pergunta

Existe uma chamada que eu posso fazer para new para tê-lo zerar memória como calloc?

Foi útil?

Solução

Ao contrário do que alguns estão dizendo em suas respostas, ele é possível.

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

irá zerar inicializar todos os personagens (na realidade, ele é chamado de valor de inicialização. Mas o valor-inicialização vai ser zero-inicialização para todos os seus membros de uma matriz do tipo escalar). Se é isso que você está depois.

Vale a pena notar que ele faz também trabalho para (matrizes de) classe-Tipos sem usuário declarou construtor caso em que qualquer membro deles é o valor inicializado:

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

Não é uma extensão ou algo assim. Ele trabalhou e se comportou da mesma maneira em C ++ 98 também. Apenas não foi chamado inicialização padrão em vez de inicialização valor. inicialização de zero, no entanto, é feito em ambos os casos para escalares ou matrizes de escalar ou tipos POD.

Outras dicas

Não, mas é bastante fácil para criar uma nova versão que age como calloc. Isso pode ser feito da mesma maneira que a versão não-lance de novo é implementado.

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;
}

Agora você pode fazer o seguinte para obter novo com a memória zero'd

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

Além disso você precisa fazer outras coisas divertidas como definir novos [] que é bastante para a frente também.

No. Também nem sequer pensar em fazer algo como:

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

Você pode acabar destruindo seu VTABLE (se sua classe tem um).

Eu recomendaria usar construtores para limpar a memória interna (variáveis) de sua classe.

Não. Será sempre o padrão-inicializar o item alocada (s), que no caso de primitivas não faz nada. Você vai ter que segui-lo com uma chamada std :: uninitialized_fill_n ou similar.

Você poderia fazer uma sobrecarga global new operador e tê-lo pegar a memória cru de calloc(). Desta forma, a memória é eliminada antes de construtores começar a correr assim não há não há problemas.

Qualquer classe que substitui novas por si só não vai ter o seu calloc() especial à base de new, mas depois que a classe deve ser inicializar-se corretamente de qualquer maneira.

Não se esqueça de substituir tanto new e delete e as versões 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); 
}

Note que essas versões simples não são completamente exatamente o que deveria ser - o operador new deve ser executado em um loop chamando o new_handler (se estiver instalado) e apenas lançar a exceção bad_alloc se não houver new_handler. Ou algo assim, eu vou ter que procurá-lo e atualização mais tarde.

Ah, e você também pode querer substituir a versão no_throw também.

i usar uma macro:

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

usá-lo:

Whatever* myWhatever = newclear(Whatever);

(Isto usa "colocação novos" como algumas outras soluções aqui)

No.You Tem a zero manualmente a memória fora. Lembre-se, new não é apenas sobre a alocação de memória, mas também sobre a inicialização através de construtores. Este é o lugar onde calloc é útil em C (que não tem initializer funções). Você é livre para escrever um wrapper sobre new ou mesmo calloc uso, mas na maioria das vezes para não-POD objetos isso não faz muito sentido.

Se você não insistir usando new, você pode simplesmente usar vetor:. vector<char> buffer; buffer.resize(newsize); eo conteúdo será zerado

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

E você pode substituir o novo operador global se você gosta.

Você pode dizer:

vector <char> v( 100, 0 );

que cria um array contíguo de 100 caracteres usando nova, e inicializa-los todos para zero. Você pode, então, acessar a matriz com o operador do vetor [], ou fazendo:

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

Observe isso também libera de ter que chamar delete para liberar a memória alocada.

Sim.

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

Para arrays você pode usar algo como memset. Para Windows usar ZeroMemory ou SecureZeroMemory.

Editar:. Por favor, ver @ post de litb, ele mostra como você pode inicializar a 0 para arrays usando inicialização não direta como acima

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top