C++ Изменение char* внутри функции вызывает ошибку
Есть функция:
char* find_markers(char* haystack, char* marker_opening, char* marker_closing, char* &contents, char* &after)
{
// ...<marker1>... ... ...<marker2>...
// ^return ^contents ^NULL ^after
char* marker_begin = strstr(haystack, marker_opening);
if(marker_begin)
{
contents = &marker_begin[strlen(marker_opening)];
char* marker_end = strstr(contents, marker_closing);
if(marker_end)
{
haystack[marker_end-haystack] = NULL;
after = &marker_end[strlen(marker_closing)];
return marker_begin;
}
return NULL;
}
return NULL;
}
Смысл которой в том, чтобы искать в тексте пару тегов, возвращать ссылки на начало, окончание, и содержимое тега. При этом функция заменяет конец содержимого на NULL-byte, чтобы сделать его нормальной строкой.
Код тестовой программы:
int main()
{
char* text = " <tag>contents1</tag> <tag><tag> ";
char* cursor = text;
char* contents = NULL;
while(true)
{
if(!find_markers(cursor, "<tag>", "</tag>", contents, cursor)) break;
cout << contents << "\n";
}
return 0;
}
Вылетает с результатом: Process returned -1073741819 (0xC0000005) На строке: haystack[marker_end-haystack] = NULL;
Как это полечить?
Ответы (1 шт):
Для начала - запомнить, что в С++ строковый литерал менять нельзя. Это - константная строка, которая может находиться в read-only памяти. А вы в нее пытаетесь что-то писать. Как минимум UB - и в результате все, что угодно. Кстати, неужели вам компилятор об этом не ругался?
Ну, а минимальное исправление - передавать не литерал, а массив символов.
Изменить сигнатуру функции на
char* find_markers(char* haystack, const char* marker_opening,
const char* marker_closing, char* &contents, char* &after)
а вызов -
char text[] = " <tag>contents1</tag> <tag><tag> ";
Так вы делаете изменяемую копию строки. Полный текст - https://ideone.com/RNurNc
Да, и еще - раз уж у вас С++, почему бы не работать со средствами С++? Строками string, например?