As 20 linhas da vergonha
Enquanto o arroz vai cozinhado, lembrei-me de um caso curioso que aconteceu comigo no início da carreira, envolvendo gerenciamento de memória em C++. Naquela época, eu era muito mais. Mais jovem, mais rápido, mais arrogante e mais newbie…
Um colega de trabalho mais experiente estava explicando para um outro colega menos experiente que para cada new deve haver um respectivo delete. Caso contrário o objeto persistirá em memória podendo ocorrer memory leaks.
Nesse momento eu o interrompi e disse que “não necessariamente, pois basta que o objeto saia de escopo para que o destrutor seja chamado automaticamente.”.
A partir daí rolou uns 10 min de debate com argumentos e contra-argumentos, tendo toda a equipe parada assistindo. No final, metade da equipe concordava com ele e a outra metade comigo, e naquele momento ninguém tinha na cabeça uma forma de checar pra ver. Olhar na internet não era uma opção.
Como eu tinha todas as respostas, afinal já programava em PHP, Java e C++ fiquei de demonstrar posteriormente que eu estava certo.
Dias depois, num daqueles momentos filosóficos, lembrei que um endereço na memória é um número, e que é possível tanto converter um endereço para um número comum, quanto fazer o caminho inverso, embora a segunda opção normalmente seja inútil.
Bolei então uma forma de provar a minha teoria: Criaria um objeto num escopo restrito alocando com new. Guardaria o endereço desse objeto como um número comum num long fora do escopo restrito, esperaria o escopo restrito finalizar, o destrutor do obejto ser chamado e então, no escopo externo, usaria o número que representava o endereço do objeto para acessar aquela área de memória mostrando que receberia um SIGSEGV (segmentation fault) por tentar acessar uma área de memória inválida. Gerei então o código abaixo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> #include <string> using namespace std; int main(int argc, char** argv) { unsigned long num = 0; { string* str = new string("Hello World!!!"); num = (unsigned long)str; cout << "str: " << str << endl; cout << "num: " << num << endl; } cout << *((string*)num) << endl; return 0; } |
Eis que para minha surpresa o programa NÃO explodiu na minha cara. Ele funcionava corretamente demonstrando que na verdade EU era quem estava errado.
Pesquisando mais constatei que sim, para cada new deve haver um e somente delete, e mais, para cada new[] deve haver um e somente um delete[]. O que eu achava que sabia sobre gerenciamento de memória e escopos, provavelmente era alguma confusão entre diferentes linguagens.
Quando eu iniciei a discussão dias antes, eu cometi todos os erros básicos que um newbie comete:
- Se meter onde não foi chamado.
- Jurar de pé junto que está certo sem ter provas.
- Subestimar o conhecimento de alguém mais experiente.
- Achar que tem todas as respostas só porque acabou de ver isso na aula.
- Achar que só porque conhece o básico de várias linguagens, então tem todas as respostas.
Como todo bom integrante da espécie dos Homo sapiens, falei merda. A minha reação a esta descoberta foi assumir para e equipe inteira que eu estava errado, pedir desculpas por ter falado besteira e mostrar essas vinte linhas de código que usei para demonstrar isso. Além disso, mostrei todas as fontes que pesquisei, e ainda trouxe à tona outros detalhes sobre gerenciamento de memória que nos estavam escapando, como referências circulares. Isso levou até a um re-desing de algumas partes do projeto.
As minhas 20 linhas de cógigo ficaram conhecidas como “As 20 linhas da vergonha” e natualmente eu fui sacaneado por isso. Cada vez que alguém tinha alguma dúvida falavam “faz aí as 20 linhas da vegonha pra testar”. O significado era mais ou menos como “faz aí um teste simples pra não passar vergonha depois”.
O mais importante é que a minha atitude pós-cagada foi bem aceita e trouxe benefícios para a equipe. Se eu tivesse me esquivado, mais cedo ou mais tarde alguém ia provar que eu estava errado na frente de todo mundo, ou pior, nos bastidores. Admitir o erro e aprender com isso mostrou que eu estava preparado para ser contestado. Adicionalmente isso mostrou para equipe que por mais que eu parecesse arrogante (eu pareço mais do que sou…), eu sabia que era um humano comum, que errava como qualquer um, não me achando superior a ninguém. Isso abriu caminho para que outros membros da equipe se sentissem à vontade para fazer o mesmo e nós nos tornamos uma equipe ainda mais coesa.
Comments
-
Marcus Antonius
-
http://blabos.org blabos
-
Junio
-
♣♦ Cheshire Hime ♥♠
-
http://blabos.org Blabos de Blebe
-
♣♦ Cheshire Hime ♥♠
-
http://blabos.org Blabos de Blebe

