Ir para conteúdo
Fórum Script Brasil
  • 0

Esses ponteiros apontam pra áreas alocadas ou desalocadas?


Ricardo Martins

Pergunta

Quando queremos armazenar vários valores de um mesmo tipo em sequência podemos usar vetores ou ponteiros. Em essência, os dois são a mesma coisa, pois vetores também são ponteiros. Porém, vetores são ponteiros CONSTANTES e como tal possui algumas limitações, como, por exemplo, não deixar de apontar pra área que apontam pra apontar pra outras áreas.

Sendo assim, às vezes eu opto por usar ponteiros em vez de vetores, pois há momentos em que eu preciso fazer os ponteiros apontar pra outras áreas. Pra que eu possa ter essa flexibilidade no meu código, eu substituo vetores por ponteiros da seguinte forma:

int *a, *b, *c;
a= (int [5]) {1, 2, 3, 4, 5};
b= (int [5]) {11, 12};
c= (int [])  {21, 22, 23, 24, 25};
Cada um desses ponteiros apontam pra áreas de memória com 5 elementos. Eles funcionam exatamente da mesma maneira que os vetores, mas com o diferencial de ser possível mudar os endereços apontados. A mesma construção mostrada anteriormente pode ser feita usando inicializações também. Porém, nesse caso é necessário incluir mais um cast pra que o compilador não acuse erros de compilação:
int *a= (int *) (int [5]) {1, 2, 3, 4, 5};
int *b= (int *) (int [5]) {11, 12};
int *c= (int *) (int [])  {21, 22, 23, 24, 25};
A minha dúvida está relacionada com as áreas de memória para qual os ponteiros apontam. Depois que essas operações são feitas, as áreas de memória são desalocadas? Ou seja, nos exemplos, os ponteiros estão apontando pra áreas de memória desalocadas? Caso estejam apontando pra áreas devidamente alocadas, essas áreas são desalocadas quando os ponteiros passam a apontar pra outros endereços? Exemplo:
int *a= (int *) (int [5]) {1, 2, 3, 4, 5};
int b= 123;
a= &b;

Eu testei isso aqui em casa algumas vezes e nunca deu nenhum erro. Porém, eu não sei se não deu erro porque é uma construção válida da linguagem ou porque a linguagem é excessivamente permissiva, principalmente quando se trata de vetores.

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 0

Vou tentar ajudar a pensar, não julgue nada do que eu disser como uma conclusão definitiva já que, como você, estou aprendendo.

Tento levar essa questão mais para a discussão de sistemas operacionais do que características intrínsecas à linguagem. Para um SO de propósito geral (ex.: Windows, Linux), os processos são carregados na memória primária a partir de especificações contidas no cabeçalho dos arquivos executáveis. Essas informações definem o segmento de dados, o de texto (código), a área de pilha e a de heap (alocações em runtime).

Estes trechos de código que você escreveu aí em momento algum lida com alocação dinâmica (malloc ou new), esses dados, em runtime, provavelmente estão na área libberada pelo o SO para o armazenamento de dados e não no heap. Desse modo esses vetores são tratados com as mesmas regras das variáveis.

Veja um teste que fiz no debugger GDB usando um executável gerado por um código C que compilei com o gcc (GCC) 4.4.4:

CÓDIGO:

#include <stdlib.h>

int main(void)
{
  int *ptr1= (int *) (int [5]) {1, 2, 3, 4, 5};
  int b = 123;
  int *ptr2 = (int *)malloc(sizeof(int));

  return 0;
}
TESTE:
(gdb) break main
Breakpoint 1 at 0x4004f4: file ptrvet.c, line 5.
(gdb) s
The program is not being run.
(gdb) r
Starting program: /home/douplus/scriptbrasil/ptrvet 

Breakpoint 1, main () at ptrvet.c:5
(gdb) s
(gdb) s
(gdb) s
(gdb) p ptr1
$1 = (int *) 0x7fffffffdda0
(gdb) p ptr2
$2 = (int *) 0x601010
(gdb) p b
$3 = 123
(gdb) p &b
$4 = (int *) 0x7fffffffddc4
(gdb)

Repare como &b tem o endereço: 0x7fffffffddc4 que é próximo ao endereço apontado por ptr1 (0x7fffffffdda0) que pertencem ao segmento de dados. Já ptr2 aponta para uma memórica alocada dinâmicamente cujo endereço é 0x601010. Este segmento de memória primária é claramente outro, pertence ao heap.

Pensando agora em características do C / C++, a "vida" das variáveis (não estáticas e não alocadas dinamicamente) é determinada por escopos. Por tanto, pela lógica, você trabalharía com esses vetores sem risco de acesso indevido enquanto você permanecer no escopo em que os definiu.

Agora, se você tem em mente definir e trabalhar com esses vetores em uma função e retornar um ponteiro para eles, você corre sério risco de acesso indevido, pois é como trabalhar com uma variável definida em outro escopo, coisa que o C não permite. Fato, se você tentar criar uma função que retorne um ponteiro para uma variável definida dentro de seu escopo, o compilador acusa erro, para fazer isso usa-se alocação dinâmica e em alguns casos variáveis static.

Por fim, algo que penso: nunca vejo o fato da linguagem C ser "excessivamente permissiva" como um problema, cabe ao programador saber ao máximo sobre os recursos da máquina, além de ter domínio sobre a linguagem que está usando e conhecer, pelo menos em teoria, a forma como o sistema operacional em questão está gerenciando os recursos da máquina.

Editado por == Douplus ==
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...