2010-07-31 19 views
6

Estoy tratando de implementar un administrador de memoria personalizado y me pregunto si hay una mejor manera de implementar esta función, ya que cuando me preguntan sobre la aritmética del puntero void, varias personas pensaron que si tuviera un vacío * en C++, algo estuvo muy mal.Custom Memory Manager

// allocates a page of memory. 
void ObjectAllocator::allocatePage() 
{  
    //if(OAStats_.PagesInUse_ >= Config_.MaxPages_) 
     //throw exception 

    void* buffer = ::operator new(OAStats_.PageSize_); // allocate memory, no constructor call. 

    // =============== Setup the PageList_ =============== 
    GenericObject* pNewNode = ::new(buffer) GenericObject(); // Construct GenericObject for the pagelist. 
    pNewNode->Next = PageList_->Next;       // pNewNode points to wherever PageList_ pointed to. 
    PageList_->Next = pNewNode;         // PageList_ points to pNewNode 
    pNewNode = NULL;           // dont need this handle anymore 
    buffer = static_cast<char*>(buffer) + sizeof(GenericObject); // move pointer to point after the generic object. 

    // =============== Setup the FreeList_ =============== 
    for(int i=0;i<Config_.ObjectsPerPage_;++i) 
    { 
     static GenericObject* pPreviousNode = NULL;   // static variable to hold the previous node 
     pNewNode = ::new(buffer) GenericObject();   // Construct GenericObject for the freelist. 
     pNewNode->Next = pPreviousNode; 
     pPreviousNode = pNewNode; 
     buffer = static_cast<char*>(buffer) + OAStats_.ObjectSize_; // move pointer by ObjectSize. 
     ++OAStats_.FreeObjects_; 
    } 
    FreeList_->Next = pNewNode; 

    ++OAStats_.PagesInUse_; 
    ++OAStats_.Allocations_; 
} 
+2

"varias personas pensaban que si tenía un vacío * en C++, algo estaba muy mal". <- No estaría de acuerdo con eso. Los punteros vacíos tienen sus usos. Supongo que se trata de si eres parte de la comunidad 'anti-C' C++, o no. Tiendo a decir que, aunque sí, C++ es un lenguaje de nivel más alto que C, las personas a menudo hacen cosas de bajo nivel y por lo tanto, no tiene nada de malo utilizar sus características más "parecidas a C". – Stephen

+2

@Stephen: ¿Por qué tantos programadores tienen este reflejo reflejo de que cuando un concepto es criticado simplemente * tiene * que decir "no es malo, tiene su uso". Supongo que dices lo mismo sobre singletons y gotos. Pero en este caso, ¿cuáles son los usos de un vacío *? ¿Por qué debería usar un vacío * aquí? – jalf

+1

@Jalf Porque los comentarios negativos se quedan en las mentes de las personas mucho más que los comentarios positivos. Eso significa que si alguien que es nuevo en la programación, o no ha oído hablar antes de X, lee un comentario que marca X y dice que nunca debes usarlo, es probable que tome ese conocimiento y lo iguale como un hecho en su mente. Moreso, solo estaba expresando una opinión. ¿Hubiera respondido de manera similar si hubiera hecho una copia de seguridad de la vista "No usar punteros vacíos"? Aquí no, no había ninguna razón para usarlo, pero el OP simplemente dijo que la gente le había dicho que no los usara en general al codificar C++. – Stephen

Respuesta

7

Si necesita un bloque de memoria para almacenar una cadena (ANSI de 8 bits), tiene sentido declarar un puntero a dicho buffer como char y operarlo.

En su caso, necesita un bloque de memoria que es un 'blob', no tiene un tipo inherente, por lo que eligió void * para representar ese blob.

Ahora necesita incrementar ese puntero por el tamaño de algún objeto. No puede realizar operaciones aritméticas en un puntero de vacío por razones obvias, entonces, ¿qué hace? Echarlo. No hay vergüenza en ello.

5

En C++, en bytes sin formato, use un char *, y no piense menos de usted mismo. Es lo correcto para hacer (tm). Especialmente si lo envuelves en una construcción de nivel superior, como lo has hecho.

+0

¿Por qué el voto a favor, anónimo? Explique y corregiré –

2

No hay nada intrínsecamente incorrecto con el vacío *. Sin embargo, lo que a menudo vemos es que las personas que vienen de C usan en exceso el vacío * cuando deberían hacer otra cosa. Si está administrando blobs de memoria en bruto, entonces un vacío * es perfectamente apropiado. Sin embargo, rara vez hay otra razón para hacerlo.

+0

+1. Fuera de interés, ¿cuáles son las formas típicas en las que "sobreutilizar el vacío *"? – JBRWilkinson

+0

void * data, int size; memcpy (datos, búfer, tamaño); en lugar de usar plantilla y copiar constructor. – Puppy