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:
s
pointe, de la même manière que s+1
est un pointeur sur l’object après s
. 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.