referencia punteros puntero por parametros funciones declaracion como cadenas c++ c pointers local-variables

c++ - por - punteros como parametros de funciones en c



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

¿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 el "4202656"?

¿Debo copiar toda la matriz en la función replaceNumberAndPrint() para poder acceder a ella más que la primera vez?


En este código, ha utilizado el puntero a objetos locales, pero cuando una función devuelve todas las variables locales queda fuera del alcance. Si va a asignar memoria (usando la función malloc() para la asignación), entonces no se perderán datos ni se sobrescribirán.

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 imprimirá todos los elementos de la matriz y no se sobrescribirán.


La forma correcta de hacerlo es la siguiente:

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 qué necesita hacer esto, necesita saber cómo funciona sizeof (array). C (y, por lo tanto, c ++) se esfuerza por evitar copiar la matriz, y necesita que la estructura lo supere. Por qué se necesita copiar es debido a los ámbitos: el alcance de la función get_array () desaparece y cada valor que todavía se necesita de ese ámbito deberá copiarse en el alcance de la llamada.


Las variables locales salen del alcance al regresar, por lo que no puede devolver un puntero a una variable local.

Debe asignarlo dinámicamente (en el montón), utilizando malloc o new . Ejemplo:

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

Alternativamente, puede declarar la matriz como estática, teniendo en cuenta que la semántica es diferente. Ejemplo:

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

Si no sabe qué significa static , lea esta pregunta y respuesta .


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

Cuando accede a la matriz en la función replaceNumberAndPrint, el resultado no está definido. El hecho de que parece funcionar la primera vez es solo una afortunada coincidencia. Probablemente, la ubicación de la memoria que está señalando no está asignada en la pila y todavía está configurada correctamente para la primera llamada, pero la llamada a printf sobrescribe esto al presionar valores en la pila durante su operación, por lo que la segunda llamada a printf muestra algo diferente.

Necesita almacenar los datos de la matriz en el montón y pasar un puntero, o en una variable que permanece en el alcance (por ejemplo, un ámbito global o algo dentro de la función principal).


Prueba algo así. La forma en que lo hace "mata" a myArray causa si está definido 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; }


Su código invoca Comportamiento no myArray porque myArray queda fuera del alcance tan pronto como getArray() regrese y cualquier intento de utilizar (desreferencia) el puntero colgante es UB.


myArray queda fuera del alcance apenas sales de getArray. En su lugar, debe asignarle espacio en el montón.


myArray es una variable local y, por lo tanto, el puntero solo es válido hasta que se deja el final de su ámbito (que es en este caso la función que contiene getArray ). Si accede más tarde, obtendrá un comportamiento indefinido.

En la práctica, lo que sucede es que la llamada a printf sobrescribe la parte de la pila utilizada por myArray y luego contiene algunos otros datos.

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

Una alternativa que eché de menos (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 devolverlo crea una copia que sobrevive al retorno de la función. Ver la answer tp1 para detalles sobre esto.


Solución C ++:

"¿Puedo tener acceso a una variable local en una función diferente? En caso afirmativo, ¿cómo?"

La respuesta es no, no después de que la función ha terminado. Las variables locales se destruyen en ese punto.

En C++ la forma de lidiar con la devolución de matrices es administrarlas en un contenedor como std::array (tamaño fijo) o std::vector (tamaño dinámico).

P.ej:

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

En la segunda función, el valor devuelto es optimizado por el compilador, por lo que no paga el precio de copiar realmente la matriz.