Question

J'ai trouvé deux méthodes pour passer des arguments de ligne de commande dans un tableau de caractères:

int main (int argc, char **argv)
{
  const char *s1 = argv[0];
  char s2[256];
  strcpy(s2, argv[0]);

  printf("s1: %s\ns2: %s\n\n", s1, s2);
}

Compilé avec le compilateur IBM xlc sur un système AIX.

  

[MyPrompt] > ./a.out

     

s1: ./a.out

     

s2: ./a.out

Quelle implémentation (s1 ou s2) est correcte? s1 est bien parce que argv [0] peut avoir n'importe quelle longueur. s2 exige que la longueur de argv [0] < 256 caractères.

Je ne comprends pas comment / pourquoi s1 devrait fonctionner. Je pense que le membre de droite de s1 devrait être requis au moment de la compilation, mais je pense que cela est généré au moment de l'exécution.

Était-ce utile?

La solution

Si s1 fonctionne, c'est parce que le type d'argv [0] est un pointeur. Vous assignez simplement l'adresse (pas la valeur réelle), ce qui est sûr. Vous n'effectuez aucun type d'allocation ou de distribution.

Je préfère généralement la première option, car vous ne devriez lire que les variables d'argument.

Autres conseils

Si vous ne souhaitez pas modifier la chaîne, s1 fonctionnera.

Si vous souhaitez modifier la chaîne, vous pouvez en faire une copie. Vous devez utiliser les méthodes plus sûres strnlen () et strncpy () si votre système les prend en charge.

  

Je pense que le côté droit de s1   devrait être nécessaire au moment de la compilation,   mais je pense qu'il est généré à   run-time.

Non, il est requis chaque fois que l'instruction est rencontrée. Par exemple:

void f() {
   int x = 1;
   ...
}

L'entier x sera initialisé à 1 chaque fois que la fonction est appelée, pas au moment de la compilation.

s2 a la délicieuse propriété d’être sujet à un dépassement de tampon.

J'ai vu des gens changer la valeur de argv [0]. Dans certains cas, (sur certains systèmes d’exploitation), le fait de changer argv [0] fera en sorte que le programme apparaisse en ps comme quoi que vous ayez changé.

Si vous souhaitez simplement référencer l'argument sans y apporter de modification, s1 est correct.

Si vous devez modifier l'argument de quelque manière que ce soit, vous devez en faire une copie, comme dans l'exemple s2 , mais dans l'exemple s2 , vous devez vérifier explicitement voyez si la longueur est plus longue que la mémoire tampon dans laquelle vous la copiez. Par exemple, si vous prenez un argument tel que nomfichier.jpg en tant qu'entrée et que vous sauvegardez nomfichier.gif en tant que sortie, vous devez en faire une copie car vous allez modifier l'extension .jpg en .gif

Je voudrais aller avec s1, en particulier pour argv [n] où n > 0. Des choses comme s2 vous ouvrent aux attaques classiques par débordement de tampon. En gros, un utilisateur peut formater un argument de plus de 256 caractères et écraser les informations de la pile pour pouvoir exécuter le code de son choix.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top