Qual è il modo giusto per scrivere una funzione C Restituzione di un array di caratteri?

StackOverflow https://stackoverflow.com/questions/8311131

  •  25-10-2019
  •  | 
  •  

Domanda

Sono abbastanza familiarità con Java, non così in C.

In Java, se ho un metodo che fa qualcosa e restituisce una stringa, sarebbe simile:

private String doSomething(...) {
    String s;
    // do something;
    return s;
}

L'equivalente sintattica in C non sarebbe il lavoro ed è sbagliato pianura:

char* doSomething(...) {
    char s[100];
    // do something;
    return s;
}

Certo che posso fare:

char* doSomething(...) {
    char *s;
    s = malloc(100 * sizeof(char));
    // do something;
    return s;
}

, che avrebbe funzionato (credo!) Ma io raramente vedere Codici di fare in questo modo (è perché è inutilmente riempire il mucchio?)

più comunemente, vedo:

bool doSomething(char *s) {
    // do something that copies chars to s
    return true;
}

e le dichiarazioni di chiamata potrebbe essere:

char s[100];
doSomething(s);

E se io non conosco la dimensione della matrice char fino all'interno della funzione stessa? cioè non sarebbe in grado di dichiarare la matrice char fuori della funzione e quindi passare in.

Quale sarebbe il corretta modo per affrontare un tale scenario?

È stato utile?

Soluzione

Un esempio di caso allocazione statica (che si sono tenuti a pensare alla dimensione massima del buffer al momento della compilazione)

buf[MAX_NO];
do(buf, MAX_NO);

_Bool do(char *s, size_t len) { 
// use len as boundary in your operations
}

o caso l'allocazione dinamica (utilizzando malloc come hai detto e l'utilizzo di puntatori per salvare la posizione del buffer e la dimensione)

char *s = NULL;
size_t final_len;
do(&s, &final_len);

_Bool do(char** s, size_t* final_len) {
    size_t len = discoverSize();
    char* buf = (char*) malloc(sizeof(char) * len);

    *s = buf; //save memory location
    *final_len = len; //save buffer size
    // use len as boundary in your operations

}

// do whatever
free(s); //remember to free the buffer for politeness

Altri suggerimenti

Che il codice chiamante essere responsabile per l'allocazione della memoria. Passare il buffer e la lunghezza del buffer nell'esempio 2:

bool doSomething(char *s, size_t buflen)
{ 
    // do something that copies chars to s up to max of buflen
    return true; 
} 

Ciò tende a ridurre le perdite, poiché il codice chiamante è in controllo di gestione della memoria.

Per quando non è possibile conoscere la giusta dimensione della stringa restituita, utilizzare la soluzione malloc. Naturalmente si deve free la stringa, dopo aver terminato con esso.

Non è possibile restituire un array in C.

È possibile restituire un puntatore e si dovrebbe imparare (leggendo un buon libro sulla programmazione nel C lingua) la differenza tra array e puntatori.

Un linguaggio comune per restituire un puntatore allocato dinamicamente. Poi si dovrebbe avere un eloquente convenzione che libererà il puntatore.

Si potrebbe anche restituire una struttura che contiene una matrice.

addenda

Se si desidera avere un garbage collector in C, provare spazzatura di Boehm collettore

Il modo più sicuro è quello di lasciare la responsabilità di assegnare al chiamante, come detto da altri.

Ma, se non è necessario il codice rientrante e la semplicità di Java, l'equivalente di lavoro sintattica in C è:

char* doSomething(...) {
    static char s[100];
    // do something;
    return s;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top