2011-05-03 8 views
7

Possible Duplicate:
Returning local data from functions in C and C++ via pointerVolviendo matriz entera de la función sin argumentos

Necesito crear una función sin argumentos que devuelve una matriz

me sale el error: "Atención: La función devuelve la dirección de la variable local"

mi código ha sido simplificado para facilitar la lectura

int * getNums() 
{ 
    int nums[8]; 
    nums = {1,2,3,4,5,6,7,8}; 
    return nums; 
} 

me lleva a entender que cuando la función termina la Pointe r se pierde, pero ¿la matriz aún se enviará? Si no, ¿cuál es una buena forma de devolver esta matriz entera sin argumentos en la llamada a la función?

¡Apreciar la ayuda con anticipación!

Saludos

+1

Tenga en cuenta que [las matrices y los punteros no son lo mismo] (http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c). Ver también: [¿Cómo uso las matrices en C++?] (Http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c). – sbi

Respuesta

4

I am led understand that when the function ends the pointer is lost, but will the array still be sent?

el comportamiento es indefinido.

what is a good way to return this integer array with no arguments in the function call?

int nums[8]; 

num es variable local que reside en la pila. No puede devolver la referencia de una variable local. En su lugar, asigne nums con el operador new y recuerde el delete[].

int* getNums() 
{ 
    int *nums = new int[8] ; 
    // ..... 

    return nums ; 
} 

// You should deallocate the resources nums acquired through delete[] later, 
// else memory leak prevails. 
+0

'-1' de mi parte para almacenar un objeto' nuevo' en un puntero desnudo. – sbi

+0

@sbi - ¿Podría por favor elaborar su comentario para que yo pueda corregirlo? – Mahesh

+1

@Mahesh: en lugar de realizar una gestión manual de la memoria, puede utilizar punteros inteligentes como 'boost :: shared_array' en estos casos. – Naveen

1

No puede devolver una matriz simple en C++. Trate

int *getNums() 
{ 
    int *nums = new int[8]; 
    ... 
    return nums; 
} 

Ahora nums es un puntero a una matriz montón que vivir después de getNums devoluciones.

7

No, la matriz no se "enviará". Que tiene que hacer uno de estos:

  • crear la matriz de forma dinámica utilizando las nuevas
  • crear la matriz estáticamente
  • pasar la matriz en la función como un puntero
  • uso std :: vector

En la mayoría de los casos, la última es la solución preferida.

+2

'+ 1' para' std :: vector'. (Sin embargo, es posible que desee agregar 'std/boost :: array') – sbi

0
int* getNums() 
{ 
    static int nums[8]; 
    nums = {1,2,3,4,5,6,7,8}; 
    return nums; 
} 

Debe propabally trabajar ahora :)

+0

Hacer que la electricidad estática aumente su vida útil y que esté listo :) –

+0

¡Espero que la aplicación sea de un solo hilo! – ildjarn

+0

Puede que no sea obvio para el PO que esto es algo así como una variable global. Incluso con un solo hilo, puede quemarse fácilmente "creando" dos matrices y teniendo los cambios en uno reflejados en el otro. – zoul

2

Cada vez que sale de una función de todas las variables locales creadas dentro de esa función se deterioran.
Está creando una matriz local para la función y luego regresa un puntero a la matriz. El puntero devuelto apuntará a una ubicación de memoria que ya ha sido reclamada por el sistema operativo. Entonces no funcionará para ti.
En lugar de matrices, debe utilizar vectores, ya que es C++

0

Su matriz es una variable local basada en pila regular. Eso significa que desaparece cuando regresa de la función y no funciona un puntero a la misma.Usted tiene que hacer la matriz viven más tiempo, lo que se puede hacer al convertirlo en una variable estática o su asignación en el montón:

int *getArray { 
    static int foo[] = {…}; 
    return foo; 
} 

int *getArray { 
    int foo[] = calloc(numberOfItems, sizeof(int)); 
    foo = …; 
    return foo; 
} 

Ambas soluciones tienen implicaciones que usted debe saber antes de utilizar uno. A saber, la asignación estática (primera opción) es principalmente una curiosidad no waydays, ya que crea una especie de variable global y causa más problemas de los que resuelve. La matriz asignada en el montón es bastante común, pero es más habitual pasar el puntero para rellenar usando un argumento para hacer que la interfaz sea más explícita. En todos los casos, la persona que llama es responsable de liberar la memoria asignada más tarde.

Y, como otros señalan, hay incluso mejores soluciones específicas para C++, si no insiste en usar una matriz C simple.

+0

Almacenar un objeto 'nuevo' en un puntero desnudo es una muy mala idea, y su advertencia no es suficiente para compensar eso. – sbi

+0

Lo siento, comencé con una solución C, que noté la etiqueta C++ y me aventuré en un territorio desconocido. Volveré al ejemplo de la C llana con la que me siento cómodo :) Gracias por la corrección, ¿qué es exactamente lo que puede salir mal en ese caso? – zoul

+0

Si obtienes un puntero desnudo de una función, no sabes si necesitas desasignar lo que sea que apunte, y si lo sabes, no sabes cómo hacerlo. (¿Es un objeto o una matriz? ¿Y fue 'new'd o' malloc''d?) Y cada vez que hace malabares con un puntero tonto a un recurso que necesita limpiar, no es a prueba de excepciones.Para eso debes usar punteros inteligentes, preferiblemente listos para usar como 'std :: vector' o' std :: shared_array'. – sbi

5

Imagina que no sabe lo que C-arrays son y entrar en el mundo de la moderna C++:

#include <array> 
std::array<int, 8> getNums() 
{ 
    std::array<int, 8> ret = {{ 1, 2, 3, 4, 5, 6, 7, 8 }}; 
    return ret; 
} 

Si el compilador es demasiado viejo para proporcionar una std:: o std::tr1:: implementación de array<>, considere el uso boost::array<> en su lugar. O bien, considere usar std::vector<> de cualquier manera.

+2

Si 'std/tr1/boost :: array' no está disponible, entonces puede devolver una estructura que contenga la matriz; eso puede ser más eficiente que 'std :: vector', particularmente para arreglos pequeños. –

Cuestiones relacionadas