Que signifie s = 0?

J’étudie le code de la fonction strtok de la libc de bsd. Lorsque je l’ai exécuté dans ma machine, le programme a reçu le signal SIGSEGV dans s[-1] = 0 . Voici le lien vers le code.

Est-ce que s[-1] = 0 correct?

Ceci est mon code:

 #include  #include  #include "strtok.c" int main(int argc, char* argv[]) { char* str = "xxxx xxxyy fdffd"; const char* s = " "; char* token = strtok(str, s); while (token != NULL) { printf("%s\n", token); token = strtok(NULL, s); } return 0; } 

 s[-1] 

Est élargi à:

 *( s - 1 ) 

Par conséquent, si le résultat pointe sur une mémoire valide, le code est défini.

Ceci est correct car s est un pointeur que nous pouvons voir dans le projet de norme C99 que E1[E2] is identical to (*((E1)+(E2))) de la section 6.5.2.1 indice Array indique ( emphase ):

Une expression postfixée suivie d’une expression entre crochets [] est une désignation en indice d’un élément d’un object tableau. La définition de l’opérateur en indice [] est que E1 [E2] est identique à (* ((E1) + (E2))) . En raison des règles de conversion qui s’appliquent à l’opérateur binary +, si E1 est un object de tableau (de manière équivalente, un pointeur sur l’élément initial d’un object de tableau) et E2 est un entier, E1 [E2] désigne l’élément E2 de E1 (à partir de zéro).

Si s était un tableau, il ne s’agirait toutefois pas d’un code valide, car nous accéderions à une mémoire n’appartenant pas au tableau, ce qui constituerait un comportement indéfini.

s[-1] fait référence à l’object précédant l’object sur lequel s pointe.

Selon les règles de C, s[-1] équivaut à *(s-1) . Ce:

  • Calcule s-1. Le résultat est un pointeur sur l’object avant l’object sur lequel s pointe, de la même manière que s+1 est un pointeur sur l’object après s .
  • Il en fait déférence, ce qui produit une valeur pour l’object pointé.

Ainsi, s[-1] = 0 affecte 0 à l’object avant celui-ci.

s[-1] est un code légal si s pointe sur un élément d’un tableau après le premier élément (garantissant ainsi la présence d’un élément) ou s pointe un au-delà de la fin du tableau. (Il est également légal si s pointe au-delà d’un object individuel qui n’est pas dans un tableau, ce qui constitue un usage inhabituel.)

Cela devrait être OK, car quelques lignes au-dessus, c ++, donc, dans le pire des cas, nous travaillons avec (s + 1) -1.

Que s[-1] = 0 soit “correct” ou “incorrect” dépend de la valeur d’exécution de s .

Il n’y a rien de fondamentalement faux ou inhabituel à propos de s[-1] = 0 par lui-même.

Juste un pressentiment, mais je suis à peu près sûr que le strtok(3) FreeBSD est à la fois assez stable et assez bien testé.

s est un char* ; s[-1] définit le caractère qui précède celui indiqué par s à NUL .

Pouvons-nous voir votre code qui strtok(3) ? Le problème est probablement dans votre ensemble, pour ainsi dire. De plus, avez-vous lu la page de manuel?

La première fois que strtok() est appelé, str doit être spécifié. les appels suivants, souhaitant obtenir d’autres jetons à partir de la même chaîne, doivent passer un pointeur null. La chaîne de séparation, sep , doit être fournie à chaque fois et peut changer d’un appel à l’autre.