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

(Resolvido) Dúvida sobre Ponteiros e funções


Prove Yourself

Pergunta

Baseado no seguinte código:

#include <stdio.h>
#include <stdlib.h>

void foo(int *bar);

void foo(int *bar) {
    int *spam;
    spam = (int *) malloc(sizeof(int));
    *spam = 5;
    bar = spam;
}

int main(void) {
    int *bar;
    bar = (int *) malloc(sizeof(int));
    foo(bar);
    printf("%d", *bar);
    return 0;
}

Eu estou estudando ponteiros, eu sei que isso poderia ser feito de outra forma :)

Mas enfim, porque o resultado (printf) dessa função é 0 ao invés de 5? Seria o escopo? A região da memória de spam é desalocada quando acaba a função? Como bar e spam apontam para a mesma região, ele fica 0. Estou certo?

Valeu pessoal.

Editado por Prove Yourself
Link para o comentário
Compartilhar em outros sites

8 respostass a esta questão

Posts Recomendados

  • 0

O ponteiro *bar na função foo é uma variável local nesta função. Portanto ao fazer bar=spam, somente a variável local bar aponta para spam, e quando a função acaba as duas variáveis são eliminadas.

Se você quer alterar o valor de bar na função main basta fazer assim:

void foo(int *bar) {
    *bar = 5;
}

Abraço.

Link para o comentário
Compartilhar em outros sites

  • 0

Não entendi. Porque bar é local? Ele é um parâmetro/ponteiro. Lá em main() eu passo o ponteiro pra dentro...

Ou eu tenho que passar um ponteiro de um ponteiro?

Referente ao que você falou, isso eu tinha em mente. O problema é que não sei criar um ponteiro dentro de uma função e passar o ponteiro para fora dela... Como no exemplo, queria que bar, lá fora, apontasse para spam. Entendeu?

Obrigado por enquanto. Um dia entendo esses malditos ponteiros :P

Editado por Prove Yourself
Link para o comentário
Compartilhar em outros sites

  • 0

Um ponteiro nada mais é que uma variável que armazena um endereço de memória.

O que você passou é o valor do ponteiro (i.e. endereço para o qual ele aponta, não deve-se confundir com o valor da variável apontada). Se quiser alterar o local para o qual um ponteiro aponta deverá utilizar ponteiros de ponteiros.

Quanto à variável spam, o ponteiro é desalocado (spam), mas o valor na memória (*spam) não, aquela região da memória continuará tendo o valor 5.

Como no exemplo, queria que bar, lá fora, apontasse para spam. Entendeu?

Nesse caso há duas opções. A primeira é retornar o ponteiro spam e, na outra função, atribuir bar a esse retorno:

int* funcao1()
{
    int* p=(int*)malloc(sizeof int);
    *p=5;
    return p;
}
void funcao2()
{
    int* ponteiro=funcao1(); //atribui a variável "ponteiro" ao ponteiro que a função "funcao1" retornar
}
A segunda é usando ponteiros de ponteiros:
void funcao1(int** ponteiro_para_ponteiro)
{
    *ponteiro_para_ponteiro=(int*)malloc(sizeof int); //muda o endereço para o qual o ponteiro aponta
    **ponteiro_para_ponteiro=5; //muda o valor
}
void funcao2()
{
    int* p;
    funcao1(&p); //passa o endereço do ponteiro como parâmetro
}
É como se estivéssemos modificando uma variável normal, mas essa variável que modificamos é na realidade um ponteiro. No caso de uma variável "normal", ficaria assim:
int funcao1(int* p)
{
    *p=5;
}
int funcao2()
{
    int variavel;
    funcao1(&variavel);
}

Poste aí se entendeu ou não.

Link para o comentário
Compartilhar em outros sites

  • 0

Eu entendi os exemplos e as soluções propostas... Só quero entender uma coisa... (Cara, você vai querer me bater :P)

Certo, voltando a variavel spam. Se o valor na região da memória não é desalocado, apenas o ponteiro... Porque isso ainda não imprimi 5? Ele imprime -12161954380.

#include <stdio.h>
#include <stdlib.h>

void foo(int *bar);

void foo(int *bar) {
    int *spam;
    spam = (int *) malloc(sizeof(int));
    *spam = 5;
    bar = spam;
}

int main(void) {
    int bar;
    foo(&bar);
    printf("%d", bar);
    return 0;
}

Perceba que agora não estou mais passando uma variável local e sim um ponteiro. O ponteiro bar aponta para o mesmo endereço que spam.

Obrigado por enquanto.

Link para o comentário
Compartilhar em outros sites

  • 0

O que você fez foi modificar o local para o qual o parâmetro bar da função foo (um parâmetro é semelhante a uma variável local) aponta, mas não alterou a variável bar da função main.

O nome das variáveis pode estar fazendo alguma confusão. Acho que observando o código assim deve ficar mais fácil entender:

#include <stdio.h>
#include <stdlib.h>

void foo(int *bar_parametro);

void foo(int *bar_parametro) {
    int *spam;
    spam = (int *) malloc(sizeof(int));
    *spam = 5;
    bar_parametro = spam; //modifiquei a variável bar_parametro, mas bar_de_main permanece inalterada
}

int main(void) {
    int variavel;
    int* bar_de_main=&variavel;
    foo(bar_de_main);
    printf("%d", variavel);
    return 0;
}
Para alterar o valor da varável bar_de_main, deve utilizar ponteiros de ponteiros ou retornar o valor na função foo e, na função main, fazer a atribuição (veja o código de exemplo que postei acima). No seu caso, não há necessidade real de alterar o local para o qual o ponteiro aponta, basta alterar o valor nesse local de memória. Sendo assim, pode utilizar esse código:
void foo(int* bar)
{
    *bar=5;
}

Link para o comentário
Compartilhar em outros sites

  • 0

Na verdade eu passei um ponteiro... mas em foo, ele não é local.

Veja este trecho:

int main(void) {
    int bar;
    foo(&bar);
Agora veja o seu trecho:
int main(void) {
    int variavel;
    int* bar_de_main=&variavel;
    foo(bar_de_main);

Pelo que entendi, o seu é local... o meu não é...

Obrigadão. Um abraço.

Editado por Prove Yourself
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...