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

Asked

Viewed 69 times

1

I wonder 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;
}
  • Do you have a better example? That makes sense and especially that is not reticence. This code doesn’t seem to make sense, so in this case any of it should not be used.

  • @Maniero: The question is very good and relevant, I just thought that the code example should be better elaborated, it became difficult to understand at first.

1 answer

1


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

When you use the reserved word new to initialize an object T in a buffer pre-allocated (known as Placement Syntax), new does no memory allocation, it only performs the object constructor call T, returning the even pointer of buffer preallocated.

When you use reinterpret_cast "forcing" the pointer conversion of the buffer preallocated to a pointer pointing to an object T, the call of the object constructor T is not performed.

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

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

Exit:

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

References:

Wikipedia: https://en.wikipedia.org/wiki/Placement_syntax

Stackoverflow: https://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new

cppreference: http://en.cppreference.com/w/cpp/language/new

Browser other questions tagged

You are not signed in. Login or sign up in order to post.