Is there any difference between "new" and "reinterpret_cast" for a memory buffer?

1

I would like to know if there is any difference in the final product of these two codes:

//------ Declaração curta
class ClasseA {
public:
    int valor;
    Classe() { iniciar(); }

    ClasseA * iniciar() { valor = 10; return this; }
}

int main() {
  char * buffer1 = new char[sizeof(ClasseA)];
  char * buffer2 = new char[sizeof(ClasseA)];

  //Usando operador NEW
  ClasseA* ponteiro1 = new (buffer1) ClasseA();

  //Usando reinterpret_cast
  ClasseA* ponteiro2 = reinterpret_cast<ClasseA*>(buffer2)->iniciar();

  std::cout << "Ponteiro 1 : " << ponteiro1->valor << std::endl;
  std::cout << "Ponteiro 2 : " << ponteiro2->valor << std::endl;

  delete buffer1;
  delete buffer2;

  return 1;
}
    
asked by anonymous 06.10.2017 / 18:19

1 answer

1

Basically, the difference is in the call of the constructor of the object T , which does not happen in the case of reinterpret_cast .

When you use the reserved keyword new to initialize a T object in a pre-allocated buffer (known as does not make any memory allocations, it only performs the call of the constructor of the object new , returning the same pointer of the buffer pre-allocated.

When you use T "forcing" the pre-allocated buffer pointer conversion to a pointer that points to a reinterpret_cast object, the constructor call of the T object does not is performed.

In both cases, the destructor of the object T is never is called because T only frees the pre-allocated memory from buffer and does not "know" the object delete .

Here is a functional code that illustrates the difference between the two semantics:

#include <iostream>

class Cachorro {
    public:
        Cachorro( void ) { std::cout << "Construtor" << std::endl; }
        virtual ~Cachorro( void ) { std::cout << "Destrutor" << std::endl; }
        void latir( void ) const { std::cout << "Au! Au!" << std::endl; };
};

int main(void) {
    //
    // placement_params
    //

    char * buf1 = new char[ sizeof(Cachorro) ];

    Cachorro * p1 = new(buf1) Cachorro;

    p1->latir();

    std::cout << "buf1: " << (void*) buf1 << std::endl;
    std::cout << "p1: " << (void*) p1 << std::endl;

    delete [] buf1;

    //
    // reinterpret_cast
    //

    char * buf2 = new char[ sizeof(Cachorro) ];

    Cachorro * p2 = reinterpret_cast<Cachorro*>(buf2);

    p2->latir();

    std::cout << "buf2: " << (void*) buf2 << std::endl;
    std::cout << "p2: " << (void*) p2 << std::endl;

    delete [] buf2;

    return 0;
}

Output:

Construtor
Au! Au!
buf1: 0x94c010
p1: 0x94c010
Au! Au!
buf2: 0x94c010
p2: 0x94c010

References:

Wikipedia: link

StackOverflow: link

cppreference: link

    
06.10.2017 / 22:10