Post on 06-Jul-2015
description
Um novo paradigma para o ensino de ponteiros frente à evolução de C++
Prof. Dr. Ivan Luiz Marques Ricarte
Programas das disciplinas deste concurso
Ivan L. M. Ricarte / 2014 2
Questionamentos
Ivan L. M. Ricarte / 2014 3
Estamos ensinando adequadamente a nossos alunos a
programação orientada a objetos?
Depois de C ou Pascal?
Estamos ensinando a nossos alunos os conceitos atuais
das linguagens de programação orientada a objetos?
O ensino tem acompanhado a evolução dessas linguagens?
Estamos trazendo para o ensino de futuros profissionais os
avanços obtidos em pesquisas?
Translação do conhecimento na computação?
Objetivo
Ivan L. M. Ricarte / 2014 4
Rever o ensino contemporâneo da programação orientada
a objetos, com foco no estudo de ponteiros
Ponteiros na visão tradicional
“Implementação do conceito de referência”
“Uma variável cujo conteúdo é um endereço de memória”
Usos: passagem por referência; percorrer arranjos;
alocação dinâmica de memória
Ponteiros na visão de C++ moderno
Referência polimórfica; compartilhamento de recursos
O ensino tradicional de ponteiros em C++
Ivan L. M. Ricarte / 2014
A visão tradicional de ponteiros
Ivan L. M. Ricarte / 2014 6
http://www.computer.org/portal/web/awards/lawson
Donald E. Knuth. 1974. Structured
Programming with go to Statements.
ACM Comput. Surv. 6, 4 (December
1974), 261-301.
O problema com ponteiros tradicionais
Ivan L. M. Ricarte / 2014 7
Svoboda D, Wrage L. Pointer Ownership Model. 2014 47th Hawaii
International Conference on System Sciences, p. 5090–9
Biallas S, Olesen MC, Cassez F, Huuck R. PtrTracker: Pragmatic pointer
analysis. 2013 IEEE 13th International Working Conference on Source
Code Analysis and Manipulation (SCAM) p. 69–73.
Karapinar Z, Zavrak S, Senturk A, Kara R, Erdogmus P. A game to test
pointers: Path finding. 2012 International Conference on Information
Technology Based Higher Education and Training (ITHET) p. 1–3.
2009
Apesar da evolução das técnicas e pesquisas nessa área
Ivan L. M. Ricarte / 2014 8
Savidis A. The
implementation of generic
smart pointers for advanced
defensive programming.
Softw Pract Exp
2004;34(10):977–1009
DeLozier C, Eisenberg R, Nagarakatte S, Osera P-M,
Martin MMK, Zdancewic S. Ironclad C++: A library
augmented type-safe subset of C++. ACM SIGPLAN
Not. 2013 48(10):287–304
Andrei Alexandrescu.
Modern C++ Design:
Generic Programming
and Design Patterns
Applied. Addison-
Wesley, 2001.
Tópicos relacionados a ponteiros em C++
Ivan L. M. Ricarte / 2014 9
Sintaxe da declaração e uso de variáveis ponteiros
Tipo associado ao ponteiro
Inicialização do valor de ponteiro (operador &)
Acesso ao conteúdo apontado por ponteiro (operador *)
Aritmética de ponteiros
Relação entre arranjos e ponteiros (operador [ ])
Alocação dinâmica de memória
Operadores new, delete
Inicialização de ponteiros e acesso ao conteúdo
Ivan L. M. Ricarte / 2014 10
Declaração da variável ponteiro
Uso da variável ponteiro
Situação de risco: ponteiro selvagem
Ivan L. M. Ricarte / 2014 11
Variável ponteiro cujo conteúdo não é um endereço válido
Causas
Falta de inicialização
Ponteiro inicializado para o endereço de uma variável que
não é mais válido
Variável local de uma função que já retornou
Área alocada dinamicamente que já foi liberada
Efeito
Comportamento indefinido
Ponteiro selvagem: outro exemplo
Ivan L. M. Ricarte / 2014 12
Ponteiro declarado e inicializado
Ponteiro liberado!
Uso do ponteiro após liberação
Uso do ponteiro
Situação: ponteiro para área dinamicamente alocada e liberada
Ponteiro selvagem em aplicações reais
Ivan L. M. Ricarte / 2014 13
Ozarin, N., "Lessons Learned on Five Large-Scale System
Developments," Instrumentation & Measurement Magazine, IEEE,
vol.11, no.1, pp.18-23, Feb. 2008
Ponteiro nulo
Ivan L. M. Ricarte / 2014 14
É uma situação diferente do ponteiro selvagem
Ponteiro nulo é um valor reconhecido pelo programador
Indicação de que ponteiro não está com um endereço válido
Valor de retorno válido em várias funções
Exemplo: ponteiro nulo
Ivan L. M. Ricarte / 2014 15
Ponteiro declarado
Retorno pode ser ponteiro nulo
Uso do ponteiro sem verificação
Falha de segmentação
Aritmética de ponteiros
Ivan L. M. Ricarte / 2014 16
O acesso a elementos de um bloco ou de um arranjo é
realizado por meio da aritmética de ponteiros
A[ j ] é traduzido para *(A+j)
Risco: buffer overflow
Acesso a elementos além dos limites do arranjo
Efeitos
Acessar valores indevidos ou não inicializados
Corromper variáveis alocadas em áreas contíguas
Exemplo: aritmética de ponteiros
Ivan L. M. Ricarte / 2014 17
Defeito no código
Acesso de escrita além da área alocada
-- pode corromper outros dados vizinhos
Buffer overflow em situações reais
Ivan L. M. Ricarte / 2014 18
ALOUNEH, S.; KHARBUTLI, M.; ALQUREM, R. Stack Memory Buffer Overflow Protection based on
Duplication and Randomization. Procedia Computer Science, v. 21, p. 250–256. Elsevier Masson
SAS, 2013.
O risco do vazamento de memória
Ivan L. M. Ricarte / 2014 19
SHAHRIAR, H.; NORTH, S.; MAWANGI, E. Testing of Memory Leak in Android Applications. 2014 IEEE
15th International Symposium on High-Assurance Systems Engineering. Anais... p.176–183, 2014.
Vazamento de memória
Ivan L. M. Ricarte / 2014 20
Conceito
Aplicação mantém memória que não mais utilizará
Causa
Não liberar área dinamicamente alocada após uso
Riscos
Degradação de desempenho
Interrupção da execução por falta de memória
Exemplo: vazamento de memória
Ivan L. M. Ricarte / 2014 21
1
1 – ponteiro inicializado para 0x6a1768 com conteúdo 11
ponteiro
0x6a17f8
11
Exemplo: vazamento de memória
Ivan L. M. Ricarte / 2014 22
ponteiro
0x6a17a0
11
2
2 – Mesmo ponteiro alterado; área anterior fica sem referência
121
Exemplo: vazamento de memória
Ivan L. M. Ricarte / 2014 23
ponteiro
0x6a17a0
11
3
3 – área usada pelo ponteiro é liberada
121
Exemplo: vazamento de memória
Ivan L. M. Ricarte / 2014 24
ponteiro
0x6a17a0
11
4
4 – variável ponteiro liberada (fim do escopo)
121
Esta área alocada permanece na memória
Exemplo: vazamento de memória (2)
Ivan L. M. Ricarte / 2014 25
ponteiro
... ...
...
...
...
...
...
...
...
...
...
...
Forma correta: delete [] ponteiro;
Esta área alocada permanece na memória
Blocos de memória liberados como variáveis simples
Exemplo: vazamento de memória (3)
Ivan L. M. Ricarte / 2014 26
... ...
...
...
...
...
...
...
...
...
...
... Exceção!
Toda área alocada permanece na memória
ponteiro
Falta de liberação por problema durante a execução
A evolução para uma programação com ponteiros mais robusta
Ivan L. M. Ricarte / 2014 27
Algumas propostas para introduzir classes parametrizadas
para tratar ponteiros foram incorporadas em versões
anteriores de C++
auto_ptr
Essas propostas não conseguiam resolver adequadamente
o problema
Mecanismos da linguagem não permitiam implementar a
semântica desejada para esses ponteiros
A evolução para um C++ mais seguro
Ivan L. M. Ricarte / 2014 28
Norma ISO/IEC 14882:2011
Aprovada em 12 de agosto de 2011
Usualmente referenciada como C++11 ou C++0x
Stroustrup B. Software Development for Infrastructure.
IEEE Computer 2012;45(January):47–58.
Stroustrup B. Foundations of C ++. Programming Languages
and Systems. Springer Berlin Heidelberg; 2012. p. 1–25.
Ponteiros em C++11
Ivan L. M. Ricarte / 2014
Conceito de ponteiros inteligentes
Ivan L. M. Ricarte / 2014 30
In brief, smart pointers are C++ objects that simulate
simple pointers by implementing operator-> and the
unary operator*. In addition to sporting pointer syntax
and semantics, smart pointers often perform useful
tasks—such as memory management or locking—under
the covers, thus freeing the application from carefully
managing the lifetime of pointed-to objects.
Andrei Alexandrescu,
Modern C++ Design: Generic Programming and Design Patterns Applied.
Addison-Wesley, 2001.
Estrutura mínima de um ponteiro inteligente
Ivan L. M. Ricarte / 2014 31
Inicialização
Liberação do recurso ao fim da vida do objeto
Sobrecarga dos
operadores básicos
Referência para o recurso
Uso do ponteiro inteligente básico
Ivan L. M. Ricarte / 2014 32
Criação
Uso
Liberação
Novos ponteiros em C++
Ivan L. M. Ricarte / 2014 33
Classes parametrizadas (definidas em memory) para ponteiros
inteligentes:
unique_ptr
shared_ptr
Seleção da classe de ponteiro reflete a intenção do programador
em seu uso
Ao contrário do que ocorre com ponteiro tradicional
Tornam programação mais simples e código mais robusto
Implementam o princípio RAII (Resource Acquisition Is
Initialization)
Efeito do RAII
Ivan L. M. Ricarte / 2014 34
Ponteiro tradicional Ponteiro inteligente
Declaração
Criação (segura)
Destrutor invocado ao fim do escopo
Classe que sinaliza
criação e destruição
O ponteiro unique_ptr
Ivan L. M. Ricarte / 2014 35
Existe uma única referência para o objeto apontado
Ponteiro não pode ser copiado
Posse do ponteiro pode ser transferida
Conteúdo é movido e área anterior passa a ser inválida
Mover é sempre mais eficiente que copiar
Utiliza novos recursos introduzidos na linguagem C++
Referência rvalor e a semântica de mover
Exemplo: unique_ptr
Ivan L. M. Ricarte / 2014 36
O mesmo aconteceria ao armazenar o ponteiro em um container
ou passá-lo como argumento para uma função.
Não permite a cópia!
Referência rvalor
Ivan L. M. Ricarte / 2014 37
Lvalor é algo do qual se pode obter o endereço
Rvalor não se pode obter o endereço
Tipicamente, variável temporária numa expressão ou um
valor de retorno de um método ou função
Sendo temporária, não precisa ser mantida após utilizada –
mover seu conteúdo é mais eficiente que copiá-lo
Sintaxe para referências em C++11:
T&: referência lvalor
T&&: referência rvalor
Exemplo: identificando um rvalor
Ivan L. M. Ricarte / 2014 38
Método para ser usado com lvalor
Método para ser usado com rvalor
lvalor
rvalor
Cópia e atribuição de unique_ptr
Ivan L. M. Ricarte / 2014 39
Na especificação da classe, define construtor para rvalor
public:
MeuPtr (const MeuPtr&&);
MeuPtr& operator=(MeuPtr&&);
Desabilita o acesso público dos mecanismos de construção e
cópia com lvalor
private:
MeuPtr (const MeuPtr&);
MeuPtr const operator= (const MeuPtr&);
Para transferir a posse do ponteiro explicitamente, introduz
função move()
Para transferir a posse de unique_ptr
Ivan L. M. Ricarte / 2014 40
pont1 deixa de
ser válido
(nullptr)
Estabelece um contrato de uso para o ponteiro:
1. Há apenas uma referência para o recurso alocado
2. Quando a referência deixar de existir, o recurso é liberado
O ponteiro shared_ptr
Ivan L. M. Ricarte / 2014 41
Ponteiro para um recurso que pode ser compartilhado
Com controle do número de referências
Quando última referência deixa de existir,
recurso é liberado
Exemplo: shared_ptr
Ivan L. M. Ricarte / 2014 42
Fim do escopo mas não é a última referência:
destrutor não é invocado
Cópia do ponteiro
Risco em compartilhar referências
Ivan L. M. Ricarte / 2014 43
Referências cíclicas
Exemplo: objeto tem que notificar todos os demais
objetos de uma coleção
Observer 1 Observer 2
O problema da referência cíclica
Ivan L. M. Ricarte / 2014 44
Construtor
Destrutor
Objetos construídos
Cada objeto referencia o outro (referência compartilhada)
Fim do escopo das referências,
mas recursos não são liberados
(vazamento de memória)
Referência compartilhada
Solução com weak_ptr
Ivan L. M. Ricarte / 2014 45
Cada objeto referencia o outro, mas sem posse (referência fraca)
Referência fraca
Referência fraca não detém a
posse do recurso alocado
(sem vazamento de memória)
Destrutores invocados
Conclusão: um novo paradigma para o ensino de ponteiros
Ivan L. M. Ricarte / 2014
A mudança de paradigma
Ivan L. M. Ricarte / 2014 47
Uso tradicional de ponteiros
Passagem por referência
Manipulação de arranjos
Relação entre operador [ ] e aritmética de ponteiros
Alocação dinâmica de memória
No C++ moderno, essa relação é quebrada
STL define classes para agregados, com controle interno da
alocação e acesso
string, array, vector
Ponteiros: foco em referências
Apenas unique_ptr sobrecarrega operador [ ]
A mudança de paradigma: ponteiros
Ivan L. M. Ricarte / 2014 48
Quando usar ponteiros tradicionais em C++?
Praticamente nunca
Quando usar os ponteiros inteligentes em C++?
Apenas quando a semântica de ponteiros for necessária
Quando um objeto precisa ser compartilhado
Quando é necessário fazer uma referência polimórfica
Para as demais situações, usar as classes da biblioteca
padrão de C++ (STL)
Paradigma tradicional para o ensino de C++
Ivan L. M. Ricarte / 2014 49
Ponteiros convencionais
(estilo C) como um
conhecimento prévio para
o ensino da programação
orientada a objetos
Um novo paradigma para o ensino de C++
Ivan L. M. Ricarte / 2014 50
Ponteiros inteligentes introduzidos apenas quando
necessário
Programação polimórfica
Programação concorrente
Ponteiros convencionais podem ser abordados no
contexto de uma disciplina de manutenção de
código e refatoração
Desdobramentos
Ivan L. M. Ricarte / 2014 51
Pós-graduação e pesquisa
Estratégias de refatoração de código C++ para utilização dos
novos ponteiros
Novas abordagens para análise de falhas de software em C++
moderno
Extensão
Atualização de conhecimentos para programadores C++
Capacitação de docentes
Graduação
Formação de excelência, alinhada aos avanços científicos
Referências
Ivan L. M. Ricarte / 2014 52
ALEXANDRESCU, A. Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley, 2001.
ALOUNEH, S.; KHARBUTLI, M.; ALQUREM, R. Stack Memory Buffer Overflow Protection based on Duplication and Randomization. Procedia Computer Science, v. 21, p.
250–256. Elsevier Masson SAS, 2013.
BIALLAS, S.; OLESEN, M. C.; CASSEZ, F.; HUUCK, R. PtrTracker: Pragmatic pointer analysis. Proc IEEE 13th International Working Conference on Source Code Analysis
and Manipulation (SCAM). p.69–73. 2013.
CPPREFERENCE.COM. C++ Reference. http://en.cppreference.com/w/
DELOZIER, C.; EISENBERG, R.; NAGARAKATTE, S.; et al. Ironclad C++: A library augmented type-safe subset of C++. ACM SIGPLAN Notices, v. 48, n. 10, p. 287–304, 2013.
HOARE, T. Null References: The Billion Dollar Mistake. QC2009 London. http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake
IEEE Computer Society. Howard ‘Bud’ Lawson. http://www.computer.org/portal/web/awards/lawson
KARAPINAR, Z.; ZAVRAK, S.; SENTURK, A.; KARA, R.; ERDOGMUS, P. A game to test pointers: Path finding. Proc International Conference on Information Technology
Based Higher Education and Training (ITHET). p.1–3, 2012.
KNUTH, D. E. Structured Programming with go to Statements. ACM Computing Surveys, v. 6, n. 4, p. 261–301, 1974.
LIPPMAN, S. B.; LAJOIE, J.; MOO, B. E. C++ Primer. 5th ed. Addison Wesley, 2012.
OZARIN, N. Lessons Learned On Five Large-Scale System Developments. IEEE Instrumentation & Measurement Magazine, v. 11, n. 1, p. 18–23, 2008.
SAVIDIS, A. The implementation of generic smart pointers for advanced defensive programming. Software: Practice and Experience, v. 34, n. 10, p. 977–1009, 2004.
SHAHRIAR, H.; NORTH, S.; MAWANGI, E. Testing of Memory Leak in Android Applications. 2014 IEEE 15th International Symposium on High-Assurance Systems Engineering.
Anais... p.176–183. Ieee. doi: 10.1109/HASE.2014.32, 2014.
STROUSTRUP, B. Foundations of C++. Programming Languages and Systems. p.1–25. Springer Berlin Heidelberg, 2012.
STROUSTRUP, B. Software Development for Infrastructure. IEEE Computer, v. 45, n. January, p. 47–58, 2012.
STROUSTRUP, B. The C++ Programming Language. 4th ed. Addison Wesley, 2013.
SVOBODA, D.; WRAGE, L. Pointer Ownership Model. Proc 47th Hawaii International Conference on System Sciences. p.5090–5099, 2014.
TOIT, S. DU. Working Draft, Standard for Programming Language C++ - N3337, 2012.
Obrigado!
Ivan L. M. Ricarte / 2014
http://faculty.dca.fee.unicamp.br/ricarte