Quelle est la bonne façon d'écrire une fonction C Retour d'un tableau de caractères?

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

  •  25-10-2019
  •  | 
  •  

Question

Je suis assez familier avec Java, pas en C.

En Java, si j'ai une méthode qui fait quelque chose et renvoie une chaîne, il ressemblerait à ceci:

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

L'équivalent syntaxique en C ne travaillerait et est simplement faux:

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

Bien sûr que je peux faire:

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

qui fonctionnerait (je pense!) Mais je vois rarement des codes qui font de cette façon (est-ce parce qu'il est inutilement remplir le tas?)

Le plus souvent, je vois:

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

Et les déclarations d'appel seraient:

char s[100];
doSomething(s);

Et si je ne sais pas la taille du tableau de caractères jusqu'à l'intérieur de la fonction elle-même? dire que je ne serais pas en mesure de déclarer le tableau de caractères en dehors de la fonction, puis le transmettre dans.

Quelle serait la correct façon de traiter avec le scénario d'un tel?

Était-ce utile?

La solution

Un exemple de cas d'allocation statique (vous êtes obligé de penser à la taille de la mémoire tampon maximale au moment de la compilation)

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

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

ou cas d'allocation dynamique (en utilisant malloc comme vous le dites et l'utilisation de pointeurs pour enregistrer l'emplacement de mémoire tampon et la taille)

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

Autres conseils

Laissez le code d'appel est responsable de l'allocation de la mémoire. Passer dans le tampon et la longueur du tampon dans l'exemple 2:

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

Ceci tend à réduire les fuites, puisque le code est en appelant le contrôle de la gestion de la mémoire.

Pour quand vous ne pouvez pas connaître la bonne taille de la chaîne retournée, utilisez la solution malloc. Bien sûr, vous devez free la chaîne, une fois que vous avez fini avec elle.

Vous ne pouvez pas retourner un tableau en C.

Vous pouvez retourner une pointeur et vous devriez apprendre (en lisant un bon livre sur la programmation dans le C langue) la différence entre les tableaux et pointeurs.

Un langage commun est de renvoyer un pointeur alloué dynamiquement. Ensuite, vous devriez avoir une telling convention qui libérera le pointeur.

Vous pouvez également retourner une structure contenant un tableau.

addendas

Si vous voulez avoir un éboueur en C, essayez collecteur des ordures Boehm

La meilleure façon est de laisser la responsabilité d'attribuer à l'appelant, comme l'a dit par d'autres.

Mais, si vous n'avez pas besoin de code rentrante et la simplicité de Java, l'équivalent de travail syntaxique en C est:

char* doSomething(...) {
    static char s[100];
    // do something;
    return s;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top