Votre programme présente deux problèmes.
D'abord, quand vous dites:
char *cmd1[20] = {NULL};
cmd1
est un tableau de 20 pointeurs vers char
. Cela signifie que cmd1[i]
pour i
dans [0,20) est un pointeur sur char
.
Il existe une règle dans C qui stipule que le passage d'un tableau à une fonction ne fait que passer le pointeur au premier élément du tableau à la fonction. À savoir, si vous aviez le code comme:
int ai[20];
f(ai);
alors le type de ai
dans l'appel de fonction est f(ai);
int *
et le pointeur est passé à f()
est égal à &ai[0]
, le premier élément de ai
.
Alors, quand vous faites:
parse_command(cmd1);
vous savez immédiatement que la « chose » est passé à parse_command()
est &cmd1[0]
, à savoir, un pointeur vers le premier élément de cmd1
. Puisque cmd1[0]
est de type char *
, vous passez un char **
à parse_command
. Par conséquent, votre déclaration:
parse_command(char *inTempString);
est faux, vous devriez faire:
parse_command(char **inTempString);
pour correspondre à votre appel. Cela suppose que parse_command()
analysera plus d'une valeur dans cmd1
. Si tel est le cas, vous devez également passer le nombre d'éléments dans cmd1
à parse_commnd()
— car il ne peut pas savoir combien d'éléments cmd1
a. Votre deuxième problème est que vous ne pouvez pas renvoyer l'adresse d'une variable locale à partir d'une fonction dans C. Comme ci-dessus, en plus d'un appel de fonction, retourner un tableau dans C, ou affecter quelque chose à un tableau dans C rend également le nom d'un tableau "decay" à un pointeur vers son premier élément.
Donc, étant donné votre fonction:
/* changed inTempString to cmd1 because that's what you probably meant */
int parse_command(char *cmd1)
{
char tempString[256];
/* call to function that assigns a string to tempString */
cmd1[0] = tempString;
/* you need to return an int from here */
}
le tempString
dans l'affectation à cmd1[0]
est en fait &tempString[0]
, à savoir, un pointeur vers le premier élément de tempString
. Mais puisque tempString
est détruit dès que la fonction retourne, le pointeur devient invalide. Vous ne pouvez pas utiliser la valeur plus tard.
En fait, en C, le nom d'un tableau se désintègre en un pointeur vers le premier élément dans tous les cas, à l'exception:
- lorsqu'il est utilisé comme opérande pour
sizeof
opérateur, et
- lorsqu'il est utilisé comme un opérande à pour être plus précis adresse de (
&
) opérateur
, dans des contextes d'objet, le nom d'un tableau ne se dégrade pas à un pointeur, et dans des contextes de valeur, il se désintègre à un pointeur . Voir this pour plus de détails.
Maintenant, comment devriez-vous résoudre votre deuxième problème? Cela dépend — vous pouvez soit allouer la mémoire dynamiquement dans parse_command()
, et affecter cette mémoire à , ou vous pouvez faire tempString
static
dans la fonction. Puisque static
les variables d'une fonction ne sont pas détruites lorsqu'une fonction revient, vous pouvez continuer à utiliser un pointeur. L'allocation dynamique est plus de travail que vous devez vous soucier de l'échec de l'allocation et vous devez vous rappeler de libérer le pointeur lorsque vous avez terminé. static
array est plus facile, mais vous devez faire attention car un autre appel à parse_command
remplacera le tableau, le rendant moins générique.
En supposant que vous voulez aller de la « mémoire dynamique » route, voici un schéma que vous pouvez utiliser:
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc and free */
int main(void) /* main returns int */
{
char *cmd1[20] = {NULL};
/* number of commands. "sizeof cmd1" is the number of bytes
used by the cmd1 array, and "sizeof cmd1[0]" is the number
of bytes used by one element of the array. The division
gives you the number of elements. This is 20 of course
but doing it this way makes sure that changing "20" to any
number works. */
size_t ncmds = sizeof cmd1/sizeof cmd1[0];
/* pass the number of commands to "parse_command", since
it can't know otherwise */
int x = parse_command(cmd1, ncmds);
int i;
for (i=0; i < x; ++i) {
printf("%s ", cmd1[i]);
free(cmd1[i]);
}
return 0; /* return a value from main */
}
int parse_command(char **cmd1, size_t ncmds)
{
char *tempString; /* we will malloc this */
int i; /* the number of mallocs done successfully */
tempString = malloc(...);
if (tempString == NULL) {
/* failure, handle gracefully */
} else {
++i; /* make sure i doesn't exceed or equal ncmds */
}
cmd1[0] = tempString;
/* do the above as many times as you need */
return i; /* the number successfully assigned to */
}
Oui - je ne suis pas clair sur l'endroit où '' cmd1' dans parse_command' vient de. Ce code semble assez buggé dans des choses comme ça, ce qui obscurcit sans doute la vraie erreur. –