Saltar al contenido

Cómo devolver un array de una función?

Este escrito fue probado por nuestros especialistas para que tengas la garantía de la veracidad de nuestra esta crónica.

Solución:

int* test();

pero sería “más C ++” usar vectores:

std::vector< int > test();

EDITAR

Aclararé algún punto. Ya que mencionaste C ++, iré con new[] y delete[] operadores, pero es lo mismo con malloc / free.

En el primer caso, escribirás algo como:

int* test() 
    return new int[size_needed];

pero no es una buena idea porque el cliente de su función no conoce realmente el tamaño del array está regresando, aunque el cliente puede desasignarlo de manera segura con una llamada a delete[].

int* theArray = test();
for (size_t i; i < ???; ++i)  // I don't know what is the array size!
    // ...

delete[] theArray; // ok.

Una mejor firma sería esta:

int* test(size_t& arraySize) 
    array_size = 10;
    return new int[array_size];

Y su código de cliente ahora sería:

size_t theSize = 0;
int* theArray = test(theSize);
for (size_t i; i < theSize; ++i)  // now I can safely iterate the array
    // ...

delete[] theArray; // still ok.

Dado que esto es C ++, std::vector es una solución ampliamente utilizada:

std::vector test() 
    std::vector vector(10);
    return vector;

Ahora no tienes que llamar delete[], ya que será manejado por el objeto, y puede iterarlo de manera segura con:

std::vector v = test();
std::vector::iterator it = v.begin();
for (; it != v.end(); ++it) 
   // do your things

que es más fácil y seguro.

¿Cómo puedo devolver un array en un método C ++ y ¿cómo debo declararlo? En t[] prueba(void); ??

Esto suena como una pregunta simple, pero en C ++ tiene bastantes opciones. En primer lugar, deberías preferir ...

  • std::vector<>, que crece dinámicamente a la cantidad de elementos que encuentre en tiempo de ejecución, o

  • std::array<> (introducido con C ++ 11), que siempre almacena una cantidad de elementos especificados en tiempo de compilación,

... ya que administran la memoria por usted, asegurando un comportamiento correcto y simplificando considerablemente las cosas:

std::vector fn()

    std::vector x;
    x.push_back(10);
    return x;


std::array fn2()  // C++11

    return 3, 4;


void caller()

    std::vector a = fn();
    const std::vector& b = fn(); // extend lifetime but read-only
                                      // b valid until scope exit/return

    std::array c = fn2();
    const std::array& d = fn2();

La práctica de crear un const La referencia a los datos devueltos a veces puede evitar una copia, pero normalmente puede confiar en la Optimización del valor de retorno, o - para vector pero no array - semántica de movimiento (introducida con C ++ 11).

Si realmente quiere usar un incorporado array (a diferencia de la clase de biblioteca estándar llamada array mencionado anteriormente), una forma es que la persona que llama reserve espacio y le diga a la función que lo use:

void fn(int x[], int n)

    for (int i = 0; i < n; ++i)
        x[i] = n;


void caller()

    // local space on the stack - destroyed when caller() returns
    int x[10];
    fn(x, sizeof x / sizeof x[0]);

    // or, use the heap, lives until delete[](p) called...
    int* p = new int[10];
    fn(p, 10);

Otra opción es envolver el array en una estructura, que, a diferencia de las matrices en bruto, es legal devolver por valor de una función:

struct X

    int x[10];
;

X fn()

    X x;
    x.x[0] = 10;
    // ...
    return x;


void caller()

    X x = fn();

Comenzando con lo anterior, si está atascado con C ++ 03, es posible que desee generalizarlo en algo más cercano a C ++ 11 std::array:

template 
struct array

    T& operator[](size_t n)  return x[n]; 
    const T& operator[](size_t n) const  return x[n]; 
    size_t size() const  return N; 
    // iterators, constructors etc....
  private:
    T x[N];
;

Otra opción es hacer que la función llamada asigne memoria en el montón:

int* fn()

    int* p = new int[2];
    p[0] = 0;
    p[1] = 1;
    return p;


void caller()

    int* p = fn();
    // use p...
    delete[] p;

Para ayudar a simplificar la gestión de los objetos del montón, muchos programadores de C ++ utilizan "punteros inteligentes" que aseguran la eliminación cuando los punteros al objeto salen de su alcance. Con C ++ 11:

std::shared_ptr p(new int[2], [](int* p)  delete[] p;  );
std::unique_ptr p(new int[3]);

Si está atascado en C ++ 03, la mejor opción es ver si la biblioteca boost está disponible en su máquina: proporciona boost::shared_array.

Sin embargo, otra opcin es tener algunos static memoria reservada por fn(), aunque esto NO ES THREAD SAFE, y significa que cada llamada a fn() sobrescribe los datos vistos por cualquiera que mantenga los punteros de llamadas anteriores. Dicho esto, puede ser conveniente (y rápido) para un código simple de un solo subproceso.

int* fn(int n)

    static int x[2];  // clobbered by each call to fn()
    x[0] = n;
    x[1] = n + 1;
    return x;  // every call to fn() returns a pointer to the same static x memory


void caller()

    int* p = fn(3);
    // use p, hoping no other thread calls fn() meanwhile and clobbers the values...
    // no clean up necessary...

No es posible devolver un array desde una función de C ++. 8.3.5[dcl.fct]/ 6:

Las funciones no deben tener un tipo de retorno de tipo array o función[...]

Las alternativas más comúnmente elegidas son devolver un valor de tipo de clase donde esa clase contiene un array, p.ej

struct ArrayHolder

    int array[10];
;

ArrayHolder test();

O para devolver un puntero al primer elemento de una asignación estática o dinámicamente array, la documentación debe indicar al usuario si necesita (y si es así cómo debe) desasignar la array al que apunta el puntero devuelto.

P.ej

int* test2()

    return new int[10];


int* test3()

    static int array[10];
    return array;

Si bien es posible devolver una referencia o un puntero a un array, es extremadamente raro ya que es una sintaxis más compleja sin ninguna ventaja práctica sobre ninguno de los métodos anteriores.

int (&test4())[10]

        static int array[10];
        return array;


int (*test5())[10]

        static int array[10];
        return &array;

Si para ti ha sido de provecho nuestro post, nos gustaría que lo compartas con otros programadores de esta forma contrubuyes a difundir nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *