¿Cómo acceder a una variable local desde una función diferente usando punteros?

Resuelto Radek Simko asked hace 13 años • 10 respuestas

¿Puedo tener acceso a una variable local en una función diferente? ¿Si es así, cómo?

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());
}

El resultado del fragmento de código anterior:

65
4202656

¿Qué estoy haciendo mal? ¿Qué significa "4202656"?

¿Tengo que copiar todo el array en la replaceNumberAndPrint()función para poder acceder a ella más que la primera vez?

Radek Simko avatar Dec 31 '10 20:12 Radek Simko
Aceptado

myArrayes una variable local y, por lo tanto, el puntero solo es válido hasta que se getArraydeja el final de su alcance (que es en este caso la función contenedora). Si accede a él más tarde, obtendrá un comportamiento indefinido.

En la práctica, lo que sucede es que la llamada a printfsobrescribe la parte de la pila utilizada por myArrayy luego contiene otros datos.

Para corregir su código, debe declarar la matriz en un alcance que dure lo suficiente (la mainfunción en su ejemplo) o asignarla en el montón. Si lo asigna en el montón, deberá liberarlo manualmente o en C++ usando RAII.

Una alternativa que me perdí (probablemente incluso la mejor aquí, siempre que la matriz no sea demasiado grande) es envolver su matriz en una estructura y así convertirla en un tipo de valor. Luego, al devolverlo, se crea una copia que sobrevive al retorno de la función. Consulte la respuesta de tp1 para obtener más detalles sobre esto.

CodesInChaos avatar Dec 31 '2010 13:12 CodesInChaos

No puede acceder a una variable local una vez que sale del alcance. Esto es lo que significa ser una variable local.

Cuando accede a la matriz en la replaceNumberAndPrintfunción, el resultado no está definido. El hecho de que parezca funcionar a la primera es sólo una afortunada coincidencia. Probablemente la ubicación de memoria a la que está apuntando no esté asignada en la pila y todavía esté configurada correctamente para la primera llamada, pero la llamada luego printfla sobrescribe al insertar valores en la pila durante su operación, razón por la cual la segunda llamada muestra printfalgo diferente.

Debe almacenar los datos de la matriz en el montón y pasar un puntero, o en una variable que permanezca dentro del alcance (por ejemplo, un valor global o algo dentro del alcance de la función principal).

James Gaunt avatar Dec 31 '2010 13:12 James Gaunt

Prueba algo así. La forma en que lo hace "mata" myArrayporque si se define localmente.

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

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());
}

Más: http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/

Editar: Como los comentarios señalaron correctamente: una mejor manera de hacerlo sería que:

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

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;
}
 avatar Dec 31 '2010 13:12