X* meuArrayX = new X[10];
Como descobrir depois, em tempo de execução, quantos objetos de "X" foram alocados em "meuArrayX"?
"É impossível!" - você diz.
Sim, sabemos que é impossível. Aprendemos isso na escola. Os livros dizem que é impossível. Mas...
Suponha que seu objeto X seja:
class X
{
public:
X(){}
~X(){ printf("Destrutor\n" ); }
};
{
public:
X(){}
~X(){ printf("Destrutor\n" ); }
};
X* meuArrayX = new X[10];
delete[] meuArrayX;
delete[] meuArrayX;
Uau! Ele imprimiu 10x a palavra "Destrutor"!
Então, de alguma forma, o programa sabe, em tempo de execução, quantos objetos foram alocados. Qual será a mágica usada pelo delete[]?
Realmente, isso é uma mágica. Não está documentado em lugar nenhum. Porém, com um pouco de engenharia reversa, é possível descobrir o que o programa faz.
Vou revelar o truque que é utilizado pelos dois principais compiladores: o gcc e o Ms Visual Studio.
O que eles fazem é simplesmente alocar, antes do primeiro elemento do array, um inteiro que guarda a quantidade de elementos criados. Quer ver?
#include <cstdio>
class X
{
public:
X(){}
~X(){ printf("Destrutor\n" ); }
};
int main()
{
X* meuArrayX = new X[20];
//criamos um ponteiro de int que aponta para os 4 bytes
//anteriores ao meuArrayX[0]
int* p = (int*)( (char*)&meuArrayX [0] - 4 );
printf("Tamanho do array: %d\n", *p );
delete[] meuArrayX;
getchar();
return 0;
}
class X
{
public:
X(){}
~X(){ printf("Destrutor\n" ); }
};
int main()
{
X* meuArrayX = new X[20];
//criamos um ponteiro de int que aponta para os 4 bytes
//anteriores ao meuArrayX[0]
int* p = (int*)( (char*)&meuArrayX [0] - 4 );
printf("Tamanho do array: %d\n", *p );
delete[] meuArrayX;
getchar();
return 0;
}
E esta é a mágica ;)
Lembrando que esta solução não é documentada, não é portável, não está na ISO do C++ e não deve ser utilizada por ninguém (como quase tudo deste blog).
Nenhum comentário:
Postar um comentário