Como inicializar um ponteiro? [RESOLVIDO]

1. Como inicializar um ponteiro? [RESOLVIDO]

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 06/01/2023 - 06:23h

Bom dia a todos!

Gostaria de saber se entendi certo minha dúvida abaixo!
Está correto minha afirmação?
// Crio um ponteiro, que não foi inicializado.
// Logo ele aponta para um lugar aleatório da memória
// E não tenho controle sobre que lugar de memória ele está apontando.
char *p;

// Seria então melhor sempre que eu declarar um ponteiro, eu inicializá-lo?
//Apontando para um ponteiro nulo? Ou seja, não apontar para lugar algum?
char *p = NULL;



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 12/01/2023 - 03:20h

Ao contrário do que esse bot horroroso disse, nem sempre um ponteiro (ou qualquer outra variável) vai ter valor indefinido: variáveis com alocação estática (globais e aquelas declaradas com o modificador static) que não seja explicitamente inicializadas com um valor são preenchidas com um valor inicial nulo. Somente variáveis automáticas (variáveis locais que não são declaradas com o especificador static) têm valores iniciais indefinidos.

Quanto a sempre colocar uma inicialização do ponteiro no momento da declaração, pode parecer uma boa ideia, mas acho que nada substitui o bom senso. Se você sabe, por exemplo, que entre a declaração da variável de tipo ponteiro e o ponto em que o programa vai (tentar) atribuir-lhe um valor útil essa variável não será usada de modo nenhum, não tem por que atribuir um valor que não será usado e depois será sumariamente substituído.

Creio que essa cultura de sempre atribuir um valor inicial fazia mais sentido na época em que o C exigia que todas as declarações de variáveis ocorressem no início do bloco, antes de qualquer outro tipo de comando. Desde o C99 (e o C++ há mais tempo ainda), que flexibilizou o local em que declarações podem acontecer, acredito que diminuiu muito a necessidade de atribuir um valor por mera segurança.

Note que minha posição crítica é com relação a generalização de que toda declaração tem de ter uma inicialização. Existem casos em que é plenamente razoável ter um valor default no momento da declaração. Por exemplo, entre as quatro alternativas abaixo, creio que a primeira é a mais fácil de ler e de manter (embora nenhuma das quatro provavelmente seria o jeito como eu implementaria uma função com esse objetivo específico; é só um exemplo para ilustrar o uso de inicialização com valor default).
void *my_alloc(char type, size_t n){
void *result=NULL;
switch(type){
case 'c': result=malloc(n); break;
case 'i': result=malloc(n*sizeof(int)); break;
case 'l': result=malloc(n*sizeof(long int)); break;
case 'q': result=malloc(n*sizeof(long long int)); break;
case 's': result=malloc(n*sizeof(short int)); break;
case 'f': result=malloc(n*sizeof(float)); break;
case 'd': result=malloc(n*sizeof(double)); break;
case 'D': result=malloc(n*sizeof(long double)); break;
case 'p': result=malloc(n*sizeof(void *)); break;
default: errno=EINVAL;
}
return result;
}
void *my_alloc(char type, size_t n){
void *result;
switch(type){
case 'c': result=malloc(n); break;
case 'i': result=malloc(n*sizeof(int)); break;
case 'l': result=malloc(n*sizeof(long int)); break;
case 'q': result=malloc(n*sizeof(long long int)); break;
case 's': result=malloc(n*sizeof(short int)); break;
case 'f': result=malloc(n*sizeof(float)); break;
case 'd': result=malloc(n*sizeof(double)); break;
case 'D': result=malloc(n*sizeof(long double)); break;
case 'p': result=malloc(n*sizeof(void *)); break;
default: result=NULL; errno=EINVAL;
}
return result;
}
void *my_alloc(char type, size_t n){
void *result;
if(type=='c')
result=malloc(n);
else if(type=='i')
result=malloc(n*sizeof(int));
else if(type=='l')
result=malloc(n*sizeof(long int));
else if(type=='q')
result=malloc(n*sizeof(long long int));
else if(type=='s')
result=malloc(n*sizeof(short int));
else if(type=='f')
result=malloc(n*sizeof(float));
else if(type=='d')
result=malloc(n*sizeof(double));
else if(type=='D')
result=malloc(n*sizeof(long double));
else if(type=='p')
result=malloc(n*sizeof(void *));
else{
errno=EINVAL;
result=NULL;
}
return result;
}
void *my_alloc(char type, size_t n){
return
type=='c'? malloc(n):
type=='i'? malloc(n*sizeof(int)):
type=='l'? malloc(n*sizeof(long int)):
type=='q'? malloc(n*sizeof(long long int)):
type=='s'? malloc(n*sizeof(short int)):
type=='f'? malloc(n*sizeof(float)):
type=='d'? malloc(n*sizeof(double)):
type=='D'? malloc(n*sizeof(long double)):
type=='p'? malloc(n*sizeof(void *)):
(errno=EINVAL), NULL
;
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)

3. Re: Como inicializar um ponteiro? [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 06/01/2023 - 06:23h

Sim, está correto! Por padrão, quando você cria um ponteiro, ele aponta para um endereço de memória aleatório, o que pode causar falhas e erros desnecessários. Para evitar isso, é sempre recomendado inicializar os ponteiros direcionando-os para um endereço de memória nulo (NULL), não apontando para nenhum lugar específico. Dessa forma, evita-se inconsistências no programa.


4. Re: Como inicializar um ponteiro? [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 12/01/2023 - 03:35h

De passagem, se eu fosse fazer a função acima, eu verificaria outras possibilidades de erro e evitaria múltiplas chamadas à mesma função.
int my_alloc(char type, size_t n){
if(n==0){
errno=EINVAL;
return NULL;
}
switch(type){
default:
errno=EINVAL;
return NULL;
case 'c': break;
case 'i': n*=sizeof(int); break;
case 'l': n*=sizeof(long int); break;
case 'q': n*=sizeof(long long int); break;
case 's': n*=sizeof(short int); break;
case 'f': n*=sizeof(float); break;
case 'd': n*=sizeof(double); break;
case 'D': n*=sizeof(long double); break;
case 'p': n*=sizeof(void *);
}
return malloc(n);
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts