Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Programa
Programa
o Defensiva
o Defensiva
em C
em C
Prof. Ulysses de Oliveira
Prof. Ulysses de Oliveira
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 2 2
Introdu
Introdu
o
o
Depura
Depura
o proativa
o proativa
Programa
Programa
o defensiva
o defensiva
o:
o:
Se um programa
Se um programa
pode
pode
apresentar bugs, eles
apresentar bugs, eles
iro se manifestar quando o programa estiver
iro se manifestar quando o programa estiver
em uso operacional
em uso operacional
Escopo e objetivos
Escopo e objetivos
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 3 3
Exemplos de Causas de Bugs Comuns
Exemplos de Causas de Bugs Comuns
char str[N];
...
gets(str);
char *s = "Bola";
...
s[0] = 'C';
1 2
char str[N];
...
printf(str);
char *s1, s2[N];
...
strcpy(s2, s1);
3 4
int F(int x)
{
if (x > 0)
return x;
}
5
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 4 4
Operadores
Operadores
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 5 5
Uso de Atribui
Uso de Atribui
o em vez de
o em vez de
Igualdade ou
Igualdade ou
Vice
Vice
-
-
versa
versa
o =, ou vice
o =, ou vice
-
-
versa
versa
Precau
Precau
es
es
:
:
o
o
Usar
Usar
lint
lint
e um bom compilador com
e um bom compilador com
Wall
Wall
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 6 6
Uso de Atribui
Uso de Atribui
o em vez de
o em vez de
Igualdade ou
Igualdade ou
Vice
Vice
-
-
versa
versa
Exemplos:
Exemplos:
int x;
...
if (10 = x)
...
2
int x;
...
if (x = 10)
...
1
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 7 7
Uso de Atribui
Uso de Atribui
o em vez de
o em vez de
Igualdade ou
Igualdade ou
Vice
Vice
-
-
versa
versa
o e teste
o e teste
numa
numa
cita a inten
cita a inten
o
o
Exemplo
Exemplo
melhor escrever:
melhor escrever:
if ( (p = malloc(sizeof(double))) != NULL )
...
do que:
do que:
if ( p = malloc(sizeof(double)) )
...
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 8 8
Uso Incorreto de Regras de
Uso Incorreto de Regras de
Precedncia e Associatividade
Precedncia e Associatividade
o
o
de operadores so facilmente esquecidas
de operadores so facilmente esquecidas
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 9 9
Uso Incorreto de Regras de
Uso Incorreto de Regras de
Precedncia e Associatividade
Precedncia e Associatividade
Exemplo
Exemplo
A inten
A inten
o do programador
o do programador
encerrar o la
encerrar o la
o
o
while
while
quando c recebe o valor
quando c recebe o valor
EOF
EOF
:
:
while (c = getc(stream) != EOF)
interpretada como:
interpretada como:
c = (getc(stream) != EOF)
Corre
Corre
o: usar parnteses
o: usar parnteses
while ((c = getc(stream)) != EOF)
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 10 10
Uso de && em vez de | | ou
Uso de && em vez de | | ou
Vice
Vice
-
-
versa
versa
decorrente do
decorrente do
uso equivocado das leis de
uso equivocado das leis de
De
De
Morgan:
Morgan:
EXPRESSO NEGADA EXPRESSO EQUIVALENTE
! ( A && B) ! A | | ! B
! ( A | | B) ! A && ! B
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 11 11
Uso de && em vez de | | ou
Uso de && em vez de | | ou
Vice
Vice
-
-
versa
versa
Exemplo:
Exemplo:
if ( !(x < 0 && y <= 10) )
equivalente a:
equivalente a:
if ( !(x < 0) || !(y <= 10) )
if ( x >= 0 || y > 10 )
ou a:
ou a:
Mas,
Mas,
no
no
equivalente a:
equivalente a:
if ( !(x < 0) && !(y <= 10) )
if ( x >= 0 && y > 10 )
nem
nem
a:
a:
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 12 12
Uso de & em vez de &&
Uso de & em vez de &&
2 && 12
2 && 12
resulta em
resulta em
1
1
2 & 12
2 & 12
resulta em
resulta em
0
0
Consulte o
Captulo 13
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 13 13
Uso de | em vez de | |
Uso de | em vez de | |
Os operadores || e | no so equivalentes;
Os operadores || e | no so equivalentes;
e.g.:
e.g.:
2 || 12
2 || 12
resulta em
resulta em
1
1
2 | 12
2 | 12
resulta em
resulta em
14
14
Consulte o
Captulo 13
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 14 14
Os Operadores L
Os Operadores L
gicos de C No So
gicos de C No So
Comutativos
Comutativos
gico bin
gico bin
rio so escolhidos
rio so escolhidos
importante:
importante:
x > 0 || ++y < 10
1
++y < 10 || x > 0
2
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 15 15
Os Operadores L
Os Operadores L
gicos de C No
gicos de C No
So Comutativos
So Comutativos
Exemplo
Exemplo
es sobre Ordem de
es sobre Ordem de
Avalia
Avalia
o de Operandos
o de Operandos
o de operandos
o de operandos
definida:
definida:
&&
&&
| |
| |
? :
? :
,
,
(v
(v
rgula)
rgula)
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 17 17
Suposi
Suposi
es sobre Ordem de
es sobre Ordem de
Avalia
Avalia
o de Operandos
o de Operandos
Exemplo:
Exemplo:
Talvez, a inten
Talvez, a inten
o do programador no seja
o do programador no seja
satisfeita:
satisfeita:
int i = 0, arA[N_ELEMENTOS], arB[N_ELEMENTOS];
...
while (i < N_ELEMENTOS)
arA[i] = arB[i++];
Solu
Solu
o:
o:
while (i < N_ELEMENTOS) {
arA[i] = arB[i];
++i;
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 18 18
Estruturas de Controle
Estruturas de Controle
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 19 19
Uso Indevido de
Uso Indevido de
Ponto
Ponto
-
-
e
e
-
-
v
v
rgula
rgula
Exemplos:
Exemplos:
while(i > 0);
--i;
if (x > max);
max = x;
Problemas
while(i > 0){;
--i;
}
if (x > max){;
max = x;
}
Precaues
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 20 20
Instru
Instru
o
o
switch
switch
-
-
case
case
sem break
sem break
switch
switch
-
-
case
case
possui efeito cascata
possui efeito cascata
desejado
desejado
Instru
Instru
es
es
break
break
anulam o efeito cascata
anulam o efeito cascata
desejado, inclui
desejado, inclui
-
-
se
se
um coment
um coment
rio
rio
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 21 21
Instru
Instru
o
o
switch
switch
-
-
case
case
sem break
sem break
Exemplos:
Exemplos:
switch (opcao) {
case 1:
x = y z;
case 2:
...
default:
...
}
Falta de break acidental
ou proposital?
switch (opcao) {
case 1:
x = y z; /* Segue-se efeito cascata */
case 2:
...
default:
...
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 22 22
Instru
Instru
o
o
do
do
-
-
while
while
Confundida
Confundida
com REPEAT
com REPEAT
-
-
UNTIL
UNTIL
o do seu corpo
o do seu corpo
at
at
que
que
uma
uma
condi
condi
o seja satisfeita
o seja satisfeita
o
o
do
do
-
-
while
while
Confundida
Confundida
com REPEAT
com REPEAT
-
-
UNTIL
UNTIL
Exemplo em Pascal:
Exemplo em Pascal:
REPEAT
...
UNTIL (x < 0) AND (y > 10);
Transcri
Transcri
o errada em C:
o errada em C:
do {
...
} while ((x < 0) && (y > 10));
Os dois la
Os dois la
Um
Um
else
else
sempre corresponde ao
sempre corresponde ao
if
if
mais
mais
pr
pr
uma exce
uma exce
o...)
o...)
Exemplo:
Exemplo:
if (x == 0)
if (y == 0)
++y;
else
--x;
Casamento
Corre
Corre
o:
o:
if (x == 0) {
if (y == 0)
++y;
} else
--x;
Casamento
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 25 25
Defini
Defini
es I ncorretas de
es I ncorretas de
Fun
Fun
es
es
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 26 26
Recurso sem Fim
Recurso sem Fim
Um caso no
Um caso no
-
-
recursivo de uma fun
recursivo de uma fun
o
o
recursiva deve ser sempre atingido
recursiva deve ser sempre atingido
Exemplo
Exemplo
:
:
int Fatorial(int n)
{
if(!n || n == 1)
return 1;
return n*Fatorial(n-1);
}
E se a funo for
chamada com um
valor negativo?
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 27 27
Recurso sem Fim
Recurso sem Fim
Solu
Solu
o
o
:
:
unsigned Fatorial(int n)
{
if(n < 0)
return 0; /* Zero indica erro */
if(!n || n == 1)
return 1;
return n*Fatorial(n-1);
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 28 28
Retorno de Zumbis
Retorno de Zumbis
Uma fun
Uma fun
o
o
de uma vari
de uma vari
vel de dura
vel de dura
o autom
o autom
tica
tica
Exemplo:
Exemplo:
char* UmaFuncao1(const char *str)
{
char aux[80];
...
return aux; /* Zumbi */
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 29 29
Retorno de Zumbis
Retorno de Zumbis
H
H
duas solu
duas solu
es:
es:
1. Usar uma vari
1. Usar uma vari
vel de dura
vel de dura
o fixa
o fixa
:
:
char* UmaFuncao2(const char *str)
{
static char aux[80];
...
return aux; /* OK. No Zumbi */
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 30 30
Retorno de Zumbis
Retorno de Zumbis
H
H
duas solu
duas solu
es:
es:
2. Usar aloca
2. Usar aloca
o dinmica de mem
o dinmica de mem
ria
ria
:
:
char* UmaFuncao3(const char *str)
{
char *aux = malloc(80*sizeof(char));
...
return aux; /* OK. No Zumbi */
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 31 31
Fun
Fun
Exemplo:
Exemplo:
#include <stdio.h>
int F(int arg)
{
if (arg > 0)
return arg;
}
int main(void)
{
printf( "\nValor retornado por F(10): %d\n",
F(10));
printf( "Valor retornado por F(-10): %d\n",
F(-10));
return 0;
}
O que ocorre, quando esta
funo chamada com um
parmetro negativo?
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 32 32
Vazamento de Mem
Vazamento de Mem
ria
ria
Se uma fun
Se uma fun
perdido:
perdido:
void F(const char *str)
{
char *p = malloc(strlen(str) + 1);
... /* Algum processamento */
/* com o bloco alocado */
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 33 33
Chamadas Incorretas de
Chamadas Incorretas de
Fun
Fun
es
es
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 34 34
Suposi
Suposi
es sobre Ordem de
es sobre Ordem de
Avalia
Avalia
o de Parmetros
o de Parmetros
o
o
no deve depender da ordem na qual os
no deve depender da ordem na qual os
parmetros so avaliados
parmetros so avaliados
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 35 35
Suposi
Suposi
o
o
de Parmetros
de Parmetros
Exemplo
Exemplo
o de
o de
Exce
Exce
o
o
Toda fun
Toda fun
Fun
Fun
es not
es not
malloc()
malloc()
,
,
calloc()
calloc()
e
e
realloc()
realloc()
fopen()
fopen()
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 37 37
Omisso de Teste de Condi
Omisso de Teste de Condi
o de
o de
Exce
Exce
o
o
Exemplo
Exemplo
em vez de usar:
em vez de usar:
FILE *stream = fopen("UmArquivo.txt", "r");
...
fgets(array, sizeof(array), stream);
Use:
Use:
FILE *stream;
...
if ((stream = fopen("UmArquivo.txt", "r")) != NULL)
if (fgets(array, sizeof(array), stream))
...
else
...
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 38 38
Omisso de Teste de Condi
Omisso de Teste de Condi
o de
o de
Exce
Exce
o
o
Algumas fun
Algumas fun
es sinalizam a ocorrncia
es sinalizam a ocorrncia
de erro por meio da vari
de erro por meio da vari
vel
vel
errno
errno
Deve
Deve
-
-
se checar se o valor desta vari
se checar se o valor desta vari
vel
vel
foi alterado ap
foi alterado ap
s a chamada de uma
s a chamada de uma
dessas fun
dessas fun
es
es
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 39 39
Omisso de Teste de Condi
Omisso de Teste de Condi
o de
o de
Exce
Exce
o
o
Exemplo
Exemplo
em vez de escrever:
em vez de escrever:
Deve
Deve
-
-
se escrever:
se escrever:
double y;
...
y = sqrt(x);
printf("Valor de y = %f", y);
E se x for
negativo?
Suponha que x
represente
uma expresso
complexa
double y;
...
errno = 0;
y = sqrt(x);
if (!errno) /* No ocorreu erro */
printf("Valor de y = %f", y);
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 40 40
Omisso de Teste em Aloca
Omisso de Teste em Aloca
o
o
Dinmica de Mem
Dinmica de Mem
ria
ria
poss
poss
o
o
Macro ASSEGURA_MALLOC
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 41 41
Implementa
Implementa
es Incorretas da
es Incorretas da
Biblioteca Padro
Biblioteca Padro
Algumas implementa
Algumas implementa
es de fun
es de fun
es da
es da
biblioteca padro no seguem as
biblioteca padro no seguem as
especifica
especifica
es do padro ISO de C
es do padro ISO de C
Sugesto
Sugesto
: consulte
: consulte
FAQs
FAQs
, newsgroups,
, newsgroups,
etc.
etc.
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 42 42
Chamadas de Fun
Chamadas de Fun
es sem
es sem
Parmetros
Parmetros
o sem
o sem
parmetros
parmetros
chamada usando
chamada usando
-
-
se apenas
se apenas
seu nome
seu nome
Em C,
Em C,
da
da
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 44 44
Uso Incorreto de scanf()
Uso Incorreto de scanf()
Erro comuns:
Erro comuns:
1.
1.
Passar vari
Passar vari
o) como
o) como
argumento
argumento
2.
2.
No checar o valor retornado
No checar o valor retornado
3.
3.
Especificador de formato e tipo de vari
Especificador de formato e tipo de vari
vel
vel
que no casam
que no casam
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 45 45
Uso Incorreto de scanf()
Uso Incorreto de scanf()
Exemplo
Exemplo
:
:
int x;
...
scanf("%d", x);
Deveria ser &x
Resultado
Resultado
: aborto ou erro l
: aborto ou erro l
gico
gico
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 46 46
Uso Incorreto de scanf()
Uso Incorreto de scanf()
Exemplo
Exemplo
:
:
#include <stdio.h>
int main(void)
{
int i;
char c;
for (i = 0; i < 5; ++i) {
fprintf(stderr, "Digite um inteiro: ");
scanf("%d", &c);
printf ("Valor de i: %d\n", i);
}
return 0;
}
Exemplo de Execuo
Digite um inteiro: 1
Valor de i: 0
Digite um inteiro: 2
Valor de i: 0
Digite um inteiro: 3
Valor de i: 0
Digite um inteiro: ^C
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 47 47
Uso Incorreto de printf()
Uso Incorreto de printf()
Bug de printf
Bug de printf
Quando o usu
Quando o usu
Um
Um
hacker
hacker
ainda pode escrever na pilha
ainda pode escrever na pilha
usando
usando
%n
%n
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 49 49
Uso Incorreto de printf()
Uso Incorreto de printf()
o Incorreto
o Incorreto
o Incorreto
o Incorreto
unsigned long
unsigned long
%lu
%lu
(e no
(e no
%
%
ul
ul
)
)
unsigned long
unsigned long
long
long
%llu
%llu
(e no
(e no
%
%
ull
ull
)
)
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 52 52
Lixo no Buffer Associado
Lixo no Buffer Associado
Entrada
Entrada
Padro
Padro
entrada padro
entrada padro
Solu
Solu
o: fun
o: fun
o
o
LimpaBuffer
LimpaBuffer
()
()
Consulte o
Captulo 2
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 53 53
No Existe Uso Correto para gets()
No Existe Uso Correto para gets()
A fun
A fun
o
o
gets()
gets()
no permite limitar o
no permite limitar o
n
n
Solu
Solu
o
o
: Usar de
: Usar de
fgets()
fgets()
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 54 54
Uso Incorreto de EOF
Uso Incorreto de EOF
Macro
Macro
EOF
EOF
-
-
la para determinar final de arquivo; e.g.:
la para determinar final de arquivo; e.g.:
char c;
FILE *stream;
...
while ((c = fgetc(stream)) != EOF)
putchar(c);
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 55 55
Uso Incorreto de EOF
Uso Incorreto de EOF
Sugesto
Sugesto
: use
: use
feof()
feof()
FILE *streamEntrada;
char c;
...
while (1) {
c = getc(streamEntrada);
...
if ( feof(streamEntrada) )
break;
...
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 56 56
Uso Incorreto de feof()
Uso Incorreto de feof()
feof()
feof()
retorna um valor diferente de zero
retorna um valor diferente de zero
ap
ap
m do
m do
final de um stream
final de um stream
-
-
processador
processador
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 58 58
Defini
Defini
Nunca use
Nunca use
#define
#define
para definir tipos:
para definir tipos:
#define tPonteiroParaChar char *
...
tPonteiroParaChar p1, p2;
Expanso
char * p1, p2;
Corre
Corre
o:
o:
typedef tPonteiroParaChar char *
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 59 59
Defini
Defini
es Incorretas de Macros
es Incorretas de Macros
Erros
Erros
frequentes
frequentes
em defini
em defini
es de
es de
macros:
macros:
Uso de ponto
Uso de ponto
-
-
e
e
-
-
v
v
rgula ao final da
rgula ao final da
defini
defini
o
o
o de um operador com
o de um operador com
efeito colateral
efeito colateral
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 61 61
Ponteiros
Ponteiros
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 62 62
Ponteiros No
Ponteiros No
-
-
iniciados
iniciados
O programa
O programa
o sem
o sem
bugs
bugs
Uma fun
Uma fun
o
o
o ou no retorna
o ou no retorna
vel esse
vel esse
ponteiro est
ponteiro est
apontando agora?
apontando agora?
Exemplo:
Exemplo:
strcpy(str, "bola");
Para onde str est
apontando agora?
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 64 64
Ponteiros
Ponteiros
rfos
rfos
Um ponteiro
Um ponteiro
o
o
"v
"v
o associado est
o associado est
livre para
livre para
aloca
aloca
Zumbis tamb
Zumbis tamb
m ocorrem em situa
m ocorrem em situa
es que no
es que no
envolvem retorno de fun
envolvem retorno de fun
es:
es:
int *p = NULL;
...
{
int x = 10;
p = &x;
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 65 65
Ponteiros
Ponteiros
rfos
rfos
Exemplo:
Exemplo:
int p1 = malloc(sizeof(int));
int p2 = p1;
...
free(p1);
Tanto p1 quanto p2
tornam-se rfos
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 66 66
Ponteiros
Ponteiros
rfos
rfos
Macro FREE():
Macro FREE():
Chama
Chama
free()
free()
e anula o ponteiro usado como
e anula o ponteiro usado como
argumento
argumento
Torna um poss
Torna um poss
vel erro l
vel erro l
gico em erro de
gico em erro de
execu
execu
o
o
Mas no
Mas no
uma panac
uma panac
ia; e.g.:
ia; e.g.:
int p1 = malloc(sizeof(int));
int p2 = p1;
...
FREE(p1);
*p1 = 10; /* Programa abortado */
...
*p2 = 0; /* Talvez um erro lgico */
Consulte o
Captulo 11
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 67 67
Ponteiros
Ponteiros
rfos
rfos
o alocado
o alocado
dinamicamente, no se deve chamar
dinamicamente, no se deve chamar
free()
free()
para cada ponteiro
para cada ponteiro
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 68 68
Ponteiro Incrementado Passa a
Ponteiro Incrementado Passa a
Apontar para Outro Endere
Apontar para Outro Endere
o
o
At
At
bvio
bvio
Exemplo:
Exemplo:
char *Copia(char *destino, const char *origem)
{
while (*destino++ = *origem++)
; /* Intencionalmente vazio */
return destino;
}
Para onde estar apontando
o ponteiro destino?
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 69 69
Indire
Indire
o
o
de Ponteiro Nulo
de Ponteiro Nulo
Algumas fun
Algumas fun
es de biblioteca aplicam o
es de biblioteca aplicam o
operador de
operador de
indire
indire
o
o
a um ponteiro
a um ponteiro
recebido como argumento
recebido como argumento
Exemplo:
Exemplo:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *p = NULL, ar[10];
strcpy(ar, p);
return 0;
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 70 70
Arrays e Strings
Arrays e Strings
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 71 71
Desrespeito aos Limites de Arrays
Desrespeito aos Limites de Arrays
os de repeti
os de repeti
o
o
Exemplo:
Exemplo:
#include <stdio.h>
int main(void)
{
int ar[5], i;
for (i = 1; i <= 5; ++i) {
ar[i] = 1;
printf("ar[%d] = %d\n", i, ar[i]);
}
return 0;
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 72 72
Desrespeito aos Limites de Arrays
Desrespeito aos Limites de Arrays
Se uma vari
Se uma vari
Sugesto
Sugesto
: declare ponteiros para strings
: declare ponteiros para strings
constantes com
constantes com
const
const
; e.g.:
; e.g.:
const char *s = "Bola";
...
*s = 'C';
O compilador
aponta o erro
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 74 74
Compara
Compara
o Incorreta de Strings
o Incorreta de Strings
Exemplo:
Exemplo:
char *s1 = "bola";
char s2[] = "bola";
...
if (s1 == s2)
printf("s1 e s2 sao iguais");
strcmp()
strcmp()
ou
ou
strncmp()
strncmp()
ou
ou
memcmp()
memcmp()
[nem sempre
[nem sempre
conveniente]
conveniente]
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 75 75
Compara
Compara
o Incorreta de Strings
o Incorreta de Strings
strcoll()
strcoll()
ou
ou
strxfrm()
strxfrm()
em conjunto com
em conjunto com
strcmp()
strcmp()
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 76 76
Strings Constantes sem
Strings Constantes sem
Acessibilidade
Acessibilidade
nico meio
nico meio
de acesso ao string
de acesso ao string
o, ocorre vazamento de
o, ocorre vazamento de
mem
mem
ria; e.g.:
ria; e.g.:
char *p = "pitomba";
...
p = "caju";
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 77 77
Uso de sizeof em vez de strlen()
Uso de sizeof em vez de strlen()
sizeof
sizeof
no deve ser usado em
no deve ser usado em
substitui
substitui
o a
o a
strlen()
strlen()
:
:
char *p = "bola";
char s1[80] = "bola";
char s2[] = "bola";
size_t tamanhoStr;
...
tamanhoStr = sizeof(p);
tamanhoStr = sizeof(s1);
tamanhoStr = sizeof(s2);
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 78 78
Fun
Fun
es que No Limitam o
es que No Limitam o
N
N
Muitas fun
Muitas fun
es de processamento de
es de processamento de
strings no limitam o n
strings no limitam o n
mero de
mero de
caracteres escritos num array
caracteres escritos num array
Sugesto
Sugesto
: use fun
: use fun
es equivalentes que
es equivalentes que
possuem essa capacidade
possuem essa capacidade
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 79 79
Fun
Fun
es que No Limitam o
es que No Limitam o
N
N
Exemplo
Exemplo
em vez de usar
em vez de usar
strcpy()
strcpy()
:
:
char s[10];
...
strcpy(s, "um longo string que corrompe memoria");
Use
Use
strncpy()
strncpy()
:
:
char s[10];
...
strncpy(s, "um longo string que corrompe memoria",
sizeof(s));
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 80 80
Fun
Fun
Algumas fun
Algumas fun
es declaradas em
es declaradas em
<string.h> ou <stdio.h> nem sempre
<string.h> ou <stdio.h> nem sempre
incluem o caractere terminal de string nos
incluem o caractere terminal de string nos
resultados de opera
resultados de opera
es com strings
es com strings
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 81 81
Fun
Fun
Exemplo
Exemplo
#include <stdio.h>
#include <string.h>
#define TAMANHO 12
int main()
{
char str[TAMANHO];
strncpy(str, "Um string grande", TAMANHO);
printf( "String apos chamada de strncpy():"
"\n\t \"%s\"\n", str );
return 0;
}
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 82 82
Strings Constantes Versus
Strings Constantes Versus
Caracteres Constantes
Caracteres Constantes
Erros
Erros
frequentes
frequentes
cometidos por iniciantes
cometidos por iniciantes
quando lidam com caracteres isolados e
quando lidam com caracteres isolados e
strings:
strings:
char *p;
...
*p = "A";
...
p = 'A';
ERRADO
ERRADO
char *p = "A"; OK
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 83 83
Aloca
Aloca
o de Espa
o de Espa
o Insuficiente
o Insuficiente
para Conter um String
para Conter um String
o Dinmica de
o Dinmica de
Mem
Mem
ria
ria
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 85 85
Zumbis Tamb
Zumbis Tamb
m Assombram o
m Assombram o
Heap
Heap
Se uma fun
Se uma fun
o aloca mem
o aloca mem
ria e retorna o
ria e retorna o
endere
endere
m Assombram o
m Assombram o
Heap
Heap
Exemplo:
Exemplo:
char *Funcao1(const char *str)
{
char *p = malloc(strlen(str) + 1);
...
free(p);
return p;
}
char *Funcao2(const char *str)
{
char *pAux = Funcao2("Boi");
...
free(pAux);
}
CORRETO
ERRADO
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 87 87
Lista Encadeada No
Lista Encadeada No
Array
Array
ndices ou
ndices ou
incrementos de ponteiros:
incrementos de ponteiros:
p = p->proximo; /* Correto */
p++; /* ERRADO */
++p; /* ERRADO */
p[2]; /* ERRADO */
p um ponteiro
para um n de uma
lista encadeada
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 88 88
Opera
Opera
es Inteiras
es Inteiras
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 89 89
Overflow
Overflow
Uma opera
Uma opera
o inteira resultar
o inteira resultar
em
em
overflow se, considerando os operandos
overflow se, considerando os operandos
como
como
unsigned
unsigned
, o resultado for negativo:
, o resultado for negativo:
int x, y;
...
if ((int)((unsigned)x + (unsigned)y) < 0)
printf("Ocorrera' overflow");
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 90 90
Opera
Opera
es de Ponto
es de Ponto
Flutuante
Flutuante
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 91 91
Arredondamentos
Arredondamentos
Uma opera
Uma opera
Exemplos (
Exemplos (
x
x
do tipo
do tipo
double
double
):
):
x = pow(10, 40) +
700 -
pow(10, 40) +
pow(10, 45) +
500 -
pow(10, 45);
x receber 0
x = pow(10, 40) -
pow(10, 40) +
pow(10, 45) -
pow(10, 45) +
700 +
500;
x receber 200
Usar
Usar
long double
long double
no melhora a situa
no melhora a situa
o
o
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 93 93
Compara
Compara
es de Ponto Flutuante
es de Ponto Flutuante
N
N
es de Ponto Flutuante
es de Ponto Flutuante
Exemplo
Exemplo
e
e
m vez de usar:
m vez de usar:
double x, y;
...
if (x == y)
...
Use:
Use:
#define DELTA 0.000001
...
double x, y;
...
if ( fabs(x y) <= DELTA )
...
Depende da
preciso desejada
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 95 95
Overflow e Underflow de Ponto
Overflow e Underflow de Ponto
Flutuante
Flutuante
s ocorrerem:
s ocorrerem:
double umDouble = 2*DBL_MAX;
...
if (umDouble == HUGE_VAL)
printf ("\nOcorreu overflow\n");
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 96 96
Erros de Portabilidade
Erros de Portabilidade
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 97 97
Erro de Portabilidade
Erro de Portabilidade
O programa
O programa
o de C, mas no em outra
o de C, mas no em outra
void main()
void main()
fflush(stdin)
fflush(stdin)
conio
conio
.h
Portabilidade
discutida em
detalhes no
Volume II de:
.h
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 98 98
void main()
void main()
tipos para
tipos para
main()
main()
:
:
int main(void)
int main(int argc, char *argv[])
Em ambos os prot
Em ambos os prot
int
int
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 99 99
fflush(stdin)
fflush(stdin)
fflush()
fflush()
serve para descarregar apenas
serve para descarregar apenas
buffers associados a streams de sa
buffers associados a streams de sa
da
da
Erro comum:
Erro comum:
fflush(stdin)
fflush(stdin)
Solu
Solu
o
o
: implementar
: implementar
LimpaBuffer
LimpaBuffer
()
()
Consulte o
Captulo 2
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 100 100
conio
conio
.h
.h
es
es
de C
de C
Fun
Fun
es mais utilizadas:
es mais utilizadas:
getch
getch
()
()
getche
getche
()
()
clrscr
clrscr
()
()
gotoxy
gotoxy
()
()
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 101 101
Concluso
Concluso
2009, Ulysses de Oliveira 2009, Ulysses de Oliveira Programa Programa o Defensiva em C o Defensiva em C 102 102
Concluso
Concluso
o em
o em
C:
C:
Apndice D
Apndice D
do
do
Volume II
Volume II
de
de
Programando
Programando
em C
em C
(
(
coming soon
coming soon
)
)
Depura
Depura
o e programa
o e programa
o defensiva so
o defensiva so
temas complexos
temas complexos
Any questions