2011-03-21 19 views
9

Estoy tratando de crear una nueva matriz de enteros que se deriva de una cadena de caracteres. Por ejemplo:Devolución de matrices/punteros desde una función

char x[] = "12334 23845 32084"; 

int y[] = { 12334, 23845, 32084 }; 

Tengo problemas para entender cómo devolver una matriz (que entiendo que no es posible) desde una función.

originalmente me trataron:

/* Convert string of integers into int array. */ 
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int x[n] = splitString(string, n); 

    return (0); 
} 

después supe que no se puede hacer esto.

¿Cómo funcionan los punteros en lo que respecta a las funciones?

Gracias.

Respuesta

15

Normalmente, necesita que la persona que llama pase la matriz de resultados.

void splitString(const char string[], int result[], int n) { 
    //.... 
} 

Esto es ventajoso porque la persona que llama puede asignar esa memoria donde quiera.

+0

Este es el método preferido. En el 99% de los casos, no tiene sentido devolver ningún tipo de puntero desde una función. – Lundin

+5

Derecha. Como se menciona en otras respuestas, puede usar 'malloc (n * sizeof (int))' en su función para asignar la memoria y devolver ese puntero, pero luego siempre debe recordar eventualmente 'liberar' la memoria también. Dado que el 'malloc' está oculto en una función en un nivel diferente de abstracción, usted es propenso a olvidar. Por lo tanto, es mejor asignar la memoria y pasar el puntero a la función, usar el resultado y luego liberar la memoria para que pueda emparejar fácilmente su 'malloc's con su' libre's. – JCooper

+0

@JCooper: la persona que llama también puede asignar esa memoria desde un grupo, fuera de la pila, o donde quiera que lo quiera colocar, pero la función no puede. – Puppy

5
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 
    return (newArray); 
} 

Esto es muy malo! La matriz newArray local de la función se destruye cuando la función retorna. Te quedarías afuera con un puntero colgando y usarlo invocaría un comportamiento indefinido.

No se puede devolver una matriz desde una función. Lo mejor que puede hacer es

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(n*sizeof(int)); // the array gets allocated on the heap rather than on the stack(1) 
    // Code 
    return (newArray); 
} 

No olvide liberar la memoria asignada.

(1) Tenga en cuenta que la norma no utiliza/define el término pila o pila como tal.

+0

Sí Ahora lo comprendo. He buscado en la web algunos ejemplos sobre cómo implementarlos correctamente, pero no puedo encontrar nada. – Garee

+0

@prasoonSaurav, por lo que has mencionado, newArray local para la función se destruye, así que devolvemos el puntero. El puntero generalmente almacena la dirección de la memoria, luego si devolvemos el puntero que contiene la dirección de la memoria que creamos dentro de la función, entonces esa memoria también se destruirá ¿Correcto? Podría explicarme por favor, no pude encontrar la respuesta –

+0

Ok, tengo la respuesta aquí https://stackoverflow.com/a/11656585/4146319 –

12

El problema es que está devolviendo un puntero a algo en la pila. Es necesario crear la matriz en el montón, y luego liberarlo cuando haya terminado:

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(sizeof(int) * n); 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int *x = splitString(string, n); 

    // use it 

    free(x); 

    return (0); 
} 
3

lugar de devolver una matriz con return (newArray), que devuelven un punteroal primer elemento de newArray.

El problema es que está asignando la matriz de forma incorrecta. Si crea una instancia con int newArray[n], la memoria se asigna en el marco de pila actual. Esa memoria se liberará tan pronto como regrese su función, y todo lo que haya en la matriz será basura. En su lugar, haga lo siguiente:

int *newArray = malloc(n * sizeof(int)); 
// etc. 
return newArray 

Mediante el uso de malloc, se puede asignar memoria en el montón, donde va a sobrevivir más allá del final del marco de pila actual. Solo recuerda llamar al free(newArray) en algún lugar de tu programa cuando hayas terminado.

1

Por supuesto que es posible. Esta es la manera que prefiero: int func(int** results)

función devuelve el número de elementos en results. results es un puntero a una matriz int.

2

Puede envolver una matriz en una estructura y luego devolver una instancia de la estructura. Lo menciono por completo, no es realmente algo que quieras hacer ya que es feo y hay mejores alternativas.

#include <stdio.h> 

struct retval 
{ 
    int a[10]; 
}; 

struct retval test() 
{ 
    struct retval v = {{1, 5, 6}}; 
    return v; 
} 

int main() 
{ 
    struct retval data = test(); 
    printf("%d %d\n", data.a[1], data.a[2]); 
} 
+0

Solo me pregunto, ¿cómo funciona esto? ¿No es "v.a" un puntero a una ubicación en la pila de "prueba"? Hace "struct retval data = test();" resultado en una copia profunda de la matriz? – Pradyumna

2

me gustaría ir de esta manera

/* Convert string of integers into int array. */ 
void splitString(char string[], int *out_arr, int n) 
{ 

    // code that fills each cell of out_arr 

} 

int main(void) 
{ 
    int x[n]; 
    splitString(string,(int *)x, n); 

    return (0); 
} 
Cuestiones relacionadas