Como acessar uma variável local de uma function diferente usando pointers?

Posso ter access a uma variável local em uma function diferente? Se sim, como?

void replaceNumberAndPrint(int array[3]) { printf("%i\n", array[1]); printf("%i\n", array[1]); } int * getArray() { int myArray[3] = {4, 65, 23}; return myArray; } int main() { replaceNumberAndPrint(getArray()); } 

A saída do pedaço de código acima:

 65 4202656 

O que estou fazendo de errado? O que significa “4202656”?

Preciso copiar o array inteiro na function replaceNumberAndPrint() para poder acessá-lo mais do que na primeira vez?

    myArray é uma variável local e, assim, o ponteiro só é válido até o final de seu escopo (que neste caso é a function de getArray ) é deixado. Se você acessá-lo mais tarde, você terá um comportamento indefinido.

    Na prática, o que acontece é que a chamada para printf sobrescreve a parte da pilha usada pelo myArray e, em seguida, contém alguns outros dados.

    Para corrigir seu código, você precisa declarar o array em um escopo que vive o suficiente (a function main do seu exemplo) ou alocá-lo no heap. Se você alocá-lo no heap, será necessário liberá-lo manualmente ou em C ++ usando RAII.

    Uma alternativa que eu perdi (provavelmente até mesmo a melhor aqui, desde que a matriz não seja muito grande) é envolver sua matriz em uma estrutura e, assim, torná-la um tipo de valor. Em seguida, o retorno cria uma cópia que sobrevive ao retorno da function. Veja a resposta da tp1 para detalhes sobre isso.

    Você não pode acessar uma variável local depois que ela sai do escopo. Isto é o que significa ser uma variável local.

    Quando você está acessando a matriz na function replaceNumberAndPrint, o resultado é indefinido. O fato de que parece funcionar pela primeira vez é apenas uma feliz coincidência. Provavelmente, o local da memory para o qual você está apontando não está alocado na pilha e ainda está configurado corretamente para a primeira chamada, mas a chamada para printf substitui isso empurrando valores para a pilha durante sua operação, e é por isso que a segunda chamada para printf exibe algo diferente.

    Você precisa armazenar os dados da matriz na pilha e passar um ponteiro, ou em uma variável que permanece no escopo (por exemplo, um global ou algo com escopo dentro da function principal).

    Tente algo assim. A maneira como você faz isso “mata” a causa myArray se ela for definida localmente.

     #include  #include  void replaceNumberAndPrint(int * array) { printf("%i\n", array[0]); printf("%i\n", array[1]); printf("%i\n" , array[2]); free(array); } int * getArray() { int * myArray = malloc(sizeof(int) * 3); myArray[0] = 4; myArray[1] = 64; myArray[2] = 23; //{4, 65, 23}; return myArray; } int main() { replaceNumberAndPrint(getArray()); } 

    Mais: http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/

    Edit: Como Comentários apontou corretamente: A melhor maneira de fazer isso seria que:

     #include  #include  void replaceNumberAndPrint(int * array) { if(!array) return; printf("%i\n", array[0]); printf("%i\n", array[1]); printf("%i\n" , array[2]); } int * createArray() { int * myArray = malloc(sizeof(int) * 3); if(!myArray) return 0; myArray[0] = 4; myArray[1] = 64; myArray[2] = 23; return myArray; } int main() { int * array = createArray(); if(array) { replaceNumberAndPrint(array); free(array); } return 0; } 

    myArray sai do escopo assim que você sai do getArray. Você precisa alocar espaço para ele no heap.

    Seu código invoca o comportamento indefinido porque myArray sai do escopo assim que getArray() retorna e qualquer tentativa de usar (dereference) o ponteiro pendente é UB.

    As variables ​​locais ficam fora do escopo no retorno, portanto, você não pode retornar um ponteiro para uma variável local.

    Você precisa alocá-lo dinamicamente (no heap), usando malloc ou new . Exemplo:

     int *create_array(void) { int *array = malloc(3 * sizeof(int)); assert(array != NULL); array[0] = 4; array[1] = 65; array[2] = 23; return array; } void destroy_array(int *array) { free(array); } int main(int argc, char **argv) { int *array = create_array(); for (size_t i = 0; i < 3; ++i) printf("%d\n", array[i]); destroy_array(array); return 0; } 

    Como alternativa, você pode declarar a matriz como estática, tendo em mente que a semântica é diferente. Exemplo:

     int *get_array(void) { static int array[] = { 4, 65, 23 }; return array; } int main(int argc, char **argv) { int *array = get_array(); for (size_t i = 0; i < 3; ++i) printf("%d\n", array[i]); return 0; } 

    Se você não sabe o que significa static , leia esta pergunta e resposta .

    O caminho certo para fazer isso é o seguinte:

     struct Arr { int array[3]; }; Arr get_array() { Arr a; a.array[0] = 4; a.array[1] = 65; a.array[2] = 23; return a; } int main(int argc, char **argv) { Arr a = get_array(); for(size_t i=0; i<3; i++) printf("%d\n", a.array[i]); return 0; } 

    Para entender por que você precisa fazer isso, você precisa saber como o sizeof (array) funciona. C (e, portanto, c ++) tenta evitar copiar o array, e você precisa que o struct passe por isso. Por que a cópia é necessária é por causa de escopos - o escopo da function get_array () desaparece e todo valor ainda necessário desse escopo precisará ser copiado para o escopo de chamada.

    Nesse código, você usou o ponteiro para objects locais, mas quando uma function retorna, todas as variables ​​locais ficam fora do escopo. Se você alocar memory (usando a function malloc() para alocação), nenhum dado será perdido ou sobrescrito.

     int* getArray(int size) { int *myArray = (int*)malloc(size*sizeof(int)); myArray[0] = 4; myArray[1] = 65; myArray[2] = 23; return myArray; } int main() { int i; int *vector = getArray(3); for(i=0;i<3;i++) { printf("%i\n",vector[i]); } getch(); return 0; } 

    Este código irá imprimir todos os elementos da matriz e não será substituído.

    Solução C ++:

    “Posso ter access a uma variável local em uma function diferente? Se sim, como?”

    A resposta é não, não depois que a function terminar. Variáveis ​​locais são destruídas nesse ponto.

    Em C++ a maneira de lidar com o retorno de arrays é gerenciá-los em um contêiner como std :: array (tamanho fixo) ou std :: vector (tamanho dynamic).

    Por exemplo:

     void replaceNumberAndPrint(const std::array& array) { printf("%i\n", array[0]); printf("%i\n", array[1]); printf("%i\n", array[2]); } std::array getArray() { std::array myArray = {4, 65, 23}; return myArray; } 

    Na segunda function, o valor retornado é otimizado pelo compilador para que você não pague o preço de realmente copiar a matriz.