Ponteiros, sizeof, tentando entender seu tamanho [RESOLVIDO]

1. Ponteiros, sizeof, tentando entender seu tamanho [RESOLVIDO]

Apprentice X
ApprenticeX

(usa Slackware)

Enviado em 06/12/2021 - 01:49h

Boa Dia a todos,

Estou tentando entender o custo em memória das coisas que vou usar, e me deparei com o ponteiro, que pelo visto não sei verificar qto ele ocupa em memória.
Sei que o ponteiro é um atalho para o objeto, mas qdo eu declaro abaixo, como posso saber o tamanho que meu char * está ocupando?
Pois abaixo eu tenho 2 variáveis (Text1 e Tex2) nitidamente de tamanhos diferentes mas parecem gastar 8 bytes iguais uma com a outra.
Fiquei na dúvida se um ponteiro gastaria menos memória, mas meio que não faz sentido isso né!
E no caso abaixo se ele aponta para alguma coisa, como saber o tamanho gasto visto que acho que abaixo eu estou medindo apenas o ponteiro e não o objeto em si!

#include <stdio.h>

int main(void) {
char Text1[] = "Good";
char *Text2 = "God";
char *Text3 = "Good 2021";

printf("Text1: %ld\n", sizeof Text1); // 5 Bytes - OK
printf("Text2: %ld\n", sizeof Text2); // 8 Bytes - PORQUE?
printf("Text3: %ld\n", sizeof Text3); // 8 Bytes - PORQUE Igual ao Menor?
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 07/12/2021 - 05:52h

ApprenticeX escreveu:

Boa Dia a todos,

Estou tentando entender o custo em memória das coisas que vou usar, e me deparei com o ponteiro, que pelo visto não sei verificar qto ele ocupa em memória.
Sei que o ponteiro é um atalho para o objeto, mas qdo eu declaro abaixo, como posso saber o tamanho que meu char * está ocupando?


É importante ter clareza de que um ponteiro é um valor, não uma variável. Até podem existir variáveis que armazenem valores que são ponteiros, e tais variáveis terão de ser declaradas com um tipo compatível com os valores que elas podem armazenar, mas ponteiros serão os valores nelas contidos, não elas próprias (até é comum que, com uma declaração tal como “int *pi;”, se diga algo como “pi é um ponteiro para inteiro” ou “o ponteiro pi”, mas isso é uma metonímia, assim como seria dizer, por causa da declaração “int i;”, que “i é um inteiro” ou falar sobre “o inteiro i”; mais correto seria dizer que pi e i contêm, respectivamente, um valor de ponteiro para inteiro e um valor inteiro).

Pois abaixo eu tenho 2 variáveis (Text1 e Tex2) nitidamente de tamanhos diferentes mas parecem gastar 8 bytes iguais uma com a outra.
Fiquei na dúvida se um ponteiro gastaria menos memória, mas meio que não faz sentido isso né!
E no caso abaixo se ele aponta para alguma coisa, como saber o tamanho gasto visto que acho que abaixo eu estou medindo apenas o ponteiro e não o objeto em si!


Espero que a explicação acima ajude a entender. Quando você declara uma variável de um tipo de dados ponteiro, determina quais tipos de valores essa variável vai armazenar. E, como você provavelmente já sabe, ponteiros são endereços de memória (enriquecidos, durante a compilação, com informação acerca dos tipos dos dados apontados — ou, em outras palavras, contidos nesses endereços).

A função dos ponteiros num programa em C é ser uma forma indireta de chegar a determinados dados: sabendo-se um endereço da memória e o tipo de dado contido nesse endereço, pode-se chegar até o dado (usando o endereço) e saber como tratá-lo (usando a informação sobre seu tipo). Essa informação indireta pode ser copiada de uma função para outra, permitindo que dados declarados ou obtidos dentro de uma função sejam lidos ou até mesmo modificados em outra função.

Mas, voltando ao ponto original, se o valor é um endereço, o tamanho de um ponteiro (ou seja: do valor correspondente a um endereço da memória) não tem por que ser maior do que a quantidade de bytes usados para representar um endereço. No seu caso, esse valor é de oito bytes porque você provavelmente está usando um sistema de 64 bits (oito bytes), que naturalmente representa seus endereços com esses mesmos 64 bits.

#include <stdio.h>

int main(void) {
char Text1[] = "Good";
char *Text2 = "God";
char *Text3 = "Good 2021";


Não confunda as declarações de Text1 com as declarações de Text2 e Text3.

A primeira declara um array com cinco elementos modificáveis e coloca dentro dele os caracteres 'G', 'o', 'o', 'd', '\0'. As outras declaram variáveis que armazenam ponteiros e copiam para elas endereços (ponteiros) dos respectivos primeiros elementos de dois arrays constantes (um com quatro caracteres e o outro com dez).

(Acho que eu já mencionei em outro tópico a questão de usar um ponteiro para caracteres não-constantes para referir-se a dados dispostos pelo programa na memória para dados constantes, e como eu acho que isso é uma falha na especificação do C, e que foi corrigida em C++.)

Quando você declara uma variável com um tipo ponteiro, aplicar sobre ela o operador sizeof vai sempre retornar o tamanho do ponteiro, que é aquele suficiente para representar um endereço. Não interessa se esse endereço veio de um escalar ou se do primeiro elemento (ou qualquer outro elemento que não o primeiro) de um array ou de um ponteiro retornado por uma função ou obtido a partir de uma conversão de tipo.


printf("Text1: %ld\n", sizeof Text1); // 5 Bytes - OK
printf("Text2: %ld\n", sizeof Text2); // 8 Bytes - PORQUE?
printf("Text3: %ld\n", sizeof Text3); // 8 Bytes - PORQUE Igual ao Menor?
}


Se você quiser manter a relação entre o ponteiro e a fonte original do dado, talvez precise trabalhar com tipos diferentes de ponteiros. Pode ter suas vantagens por um lado, mas pode perder em flexibilidade. Veja o exemplo abaixo.
const char nome[]="paulo1205";  // sizeof nome==10; sizeof *nome==1.
const char *ptr1=nome; // sizeof ptr1==sizeof (void *); sizeof *ptr1==1. (tamanho do ponteiro depende da máquina: tipicamente é 4 em máquinas de 32 bits e 8 em máquinas de 64 bits)
const char (*ptr2)[10]=&nome; // sizeof ptr2==sizeof (void *); sizeof *ptr2==10; sizeof **ptr2==1. (tamanho do ponteiro depende da máquina: tipicamente é 4 em máquinas de 32 bits e 8 em máquinas de 64 bits)



... 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
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts