um novo paradigma para o ensino de ponteiros frente à evolução de c++

53
Um novo paradigma para o ensino de ponteiros frente à evolução de C++ Prof. Dr. Ivan Luiz Marques Ricarte

Upload: ivan-ricarte

Post on 06-Jul-2015

284 views

Category:

Software


0 download

DESCRIPTION

Ponteiros existem nas linguagens de programação de alto nível há 50 anos, mas ainda são uma das principais fontes de problemas no desenvolvimento de software. A versão mais recente de C++, C++11, introduz novas classes que implementam ponteiros inteligentes (smart pointers) e que permitem o desenvolvimento de software mais seguro e robusto. No entanto, os principais cursos de graduação que optam por C++ ainda adotam a abordagem de ensinar ponteiros na tradição da linguagem C, causa dos muitos problemas citados. Nesta apresentação, ilustramos as causas desses problemas, introduzimos o conceito de ponteiros inteligentes e suas implementações em C++11, unique_ptr e shared_ptr, e propomos uma nova maneira de abordar o assunto em nossos cursos de graduação.

TRANSCRIPT

Page 1: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Prof. Dr. Ivan Luiz Marques Ricarte

Page 2: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Programas das disciplinas deste concurso

Ivan L. M. Ricarte / 2014 2

Page 3: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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?

Page 4: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 5: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

O ensino tradicional de ponteiros em C++

Ivan L. M. Ricarte / 2014

Page 6: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 7: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 8: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 9: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 10: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 11: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 12: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 13: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 14: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 15: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 16: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 17: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 18: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 19: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 20: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 21: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Exemplo: vazamento de memória

Ivan L. M. Ricarte / 2014 21

1

1 – ponteiro inicializado para 0x6a1768 com conteúdo 11

ponteiro

0x6a17f8

11

Page 22: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 23: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Exemplo: vazamento de memória

Ivan L. M. Ricarte / 2014 23

ponteiro

0x6a17a0

11

3

3 – área usada pelo ponteiro é liberada

121

Page 24: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 25: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 26: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 27: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 28: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 29: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Ponteiros em C++11

Ivan L. M. Ricarte / 2014

Page 30: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 31: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 32: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Uso do ponteiro inteligente básico

Ivan L. M. Ricarte / 2014 32

Criação

Uso

Liberação

Page 33: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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)

Page 34: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 35: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 36: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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!

Page 37: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 38: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 39: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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()

Page 40: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 41: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 42: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 43: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 44: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 45: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 46: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Conclusão: um novo paradigma para o ensino de ponteiros

Ivan L. M. Ricarte / 2014

Page 47: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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 [ ]

Page 48: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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)

Page 49: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 50: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 51: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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

Page 52: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

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.

Page 53: Um novo paradigma para o ensino de ponteiros frente à evolução de C++

Obrigado!

Ivan L. M. Ricarte / 2014

http://faculty.dca.fee.unicamp.br/ricarte