strtok дает ошибку сегментации

Почему приведенный ниже код дает Seg. Ошибка в последней строке?

char* m=ReadName(); printf("\nRead String %s\n",m); // Writes OK char* token; token=strtok(m,'-'); 

Как сказано, читайте строковые отпечатки без проблемы, но почему нельзя разделить на токены?

strtok модифицирует свой первый аргумент, следовательно, он должен быть модифицируемым.

Возможно, ReadName () возвращает указатель на массив символов только для чтения. Покажите нам свою функцию ReadName ().

Если это причина seg-faullt, вы можете создать копию массива char до того, как передать его в strtok, используя функцию strdup, например:

 char *copy = strdup(m); token = strtok(copy,'-'); .... .... free(copy); // free the copy once you are done using it. 

token=strtok(m,'-'); должен генерировать предупреждение компилятора, потому что второй параметр strtok() – это const char * указывающий на несколько разделителей, а не на один разделитель char :

 char *strtok(char *str, const char *delim); 

Код ASCII '-' равен 0x2D, ​​поэтому передача его как второго параметра strtok() приведет к тому, что strtok() будет разыменовывать адрес 0x0000002D, что вызовет нарушение segfault или нарушение доступа в большинстве современных операционных систем. Чтобы исправить это, используйте строковый литерал вместо символьного литерала: token=strtok(m,"-");

Также ReadName() вопрос о том, как выделяется возвращаемое значение ReadName() , которое другие ReadName() в своих ответах.

Невозможно точно знать, не зная, на что указывает m . Но, скорее всего, причина в том, что m указывает на память только для чтения. Поэтому вы можете распечатать его, но вы не можете писать на него.

strtok записывает в строку, поэтому он ошибочен, но printf только считывает из него, так что это не так.

Попробуй это

 char* m=ReadName(); printf("\nRead String %s\n",m); // Writes OK char temp = m[0]; m[0] = temp; // I'll bet you segfault here. 

Вероятно, это потому, что ReadName() возвращает строку. Таким образом, присваивание делает m const char * и, следовательно, вы не можете изменить какие-либо его значения (изменить строку). Итак, когда «strtok» пытается изменить «m», возникает segmentation fault

Способ устранения:

 char *m = malloc(sizeof(char)*MAX); strcpy(m, ReadName()); 

ИЛИ

 char *m = strdup(ReadName()); 

Нижеприведенный код берется из библиотеки BSD, лицензированной для обработки строк, для C, называемой zString .

https://github.com/fnoyanisi/zString

Посмотрев на реализацию функции, вы можете видеть, что strtok() (или в этом случае zstring_strtok() ) использует static *char чтобы сохранить последнее местоположение разделителя и фактически модифицирует исходную строку.

 char *zstring_strtok(char *str, const char *delim) { static char *static_str=0; /* var to store last address */ int index=0, strlength=0; /* integers for indexes */ int found = 0; /* check if delim is found */ /* delimiter cannot be NULL * if no more char left, return NULL as well */ if (delim==0 || (str == 0 && static_str == 0)) return 0; if (str == 0) str = static_str; /* get length of string */ while(str[strlength]) strlength++; /* find the first occurance of delim */ for (index=0;index в char *zstring_strtok(char *str, const char *delim) { static char *static_str=0; /* var to store last address */ int index=0, strlength=0; /* integers for indexes */ int found = 0; /* check if delim is found */ /* delimiter cannot be NULL * if no more char left, return NULL as well */ if (delim==0 || (str == 0 && static_str == 0)) return 0; if (str == 0) str = static_str; /* get length of string */ while(str[strlength]) strlength++; /* find the first occurance of delim */ for (index=0;index 

В этом сообщении объясняется различие между char s[] и char *s довольно хорошо. Так,

 char s[]="Test to pass strtok()"; /* this can be passed to strtok() */ char *m="Test to pass strtok()"; /* passing this will result in SIGSEGV */ 
  • Что может привести к ошибкам сегментации в C ++?
  • Почему этот код разворота строки C вызывает ошибку сегментации?
  • Как уловить ошибку сегментации в Linux?
  • Ошибка сегментации перед основным
  • Каков самый простой стандарт, способный создать Segfault в C?
  • Давайте будем гением компьютера.