strtok и утечки памяти

Проблема состоит в том, что по умолчанию, необходимо выйти из Вашего | для получения надлежащего чередования. Таким образом, grep интерпретирует "foo|bar" как соответствие литеральной строке "foo|bar" только, тогда как шаблон "нечто \| панель" (с завершенным |) соответствует или "нечто" или "панели".

Для изменения этого поведения используйте флаг-E:

tail -f logFile | grep -vE 'string one|string two'

, С другой стороны, использование egrep, который эквивалентен grep-E:

tail -f logFile | egrep -v 'string one|string two'

кроме того,-e является дополнительным, если Ваш шаблон не начинается с литерального дефиса. grep автоматически берет первый аргумент неопции в качестве шаблона.

5
задан guigouz 29 September 2009 в 22:52
поделиться

3 ответа

Чтобы напрямую ответить на ваш вопрос, strtok возвращает только указатель на место внутри строки, которую вы даете ему в качестве входных данных - он не выделяет для вас новую память, поэтому не нужно звоните бесплатно по любому из указателей, которые он возвращает вам взамен.

Если хотите, вы также можете изучить "strchr" и "strstr", которые являются неразрушающими способами поиска отдельных символов или последовательностей в строках.

Также обратите внимание, что распределение памяти здесь проблематично - вы используете strdup () для выделения новой строки внутри вашей функции синтаксического анализа, а затем назначаете фрагменты этого блока памяти полям "ret". Таким образом, ваш вызывающий абонент будет нести ответственность за освобождение строки strdup'd, но поскольку вы передаете эту строку только неявно внутри ret, вызывающий должен волшебным образом знать, какой указатель передать на бесплатный. (Возможно, протокол ret->, а может и нет, в зависимости от того, как выглядит ввод.)

22
ответ дан 18 December 2019 в 05:40
поделиться

strtok изменяет строку на месте, заменяя указанные символы на NULL. Поскольку строки в C заканчиваются NULL, теперь кажется, что ваш исходный указатель указывает на более короткую строку, даже если исходная строка все еще существует и по-прежнему занимает тот же объем памяти (но с символами, замененными на NULL). Я думаю, что конец строки содержит двойное значение NULL.

Короткий ответ таков: оставьте указатель на начало строкового буфера и укажите другой указатель, который является вашим «текущим» указателем в строке, как вы разбираете это. Когда вы используете strtok или перебираете строку другими способами, вы обновляете "текущий" указатель, но оставьте начальный указатель в покое. Когда вы закончите, освободите () начальный указатель. Нет утечки памяти.

5
ответ дан 18 December 2019 в 05:40
поделиться

Знаете ли вы, что можно продолжить синтаксический анализ строки, используя NULL в качестве первого параметра strtok?

Первый вызов:

char* token = strtok(string, delimiters);

Затем:

token = strtok(NULL, other_delimiters);

Это позволит вам упростить код:

int parse_url(char *url, aUrl *ret)
{
//get protocol
char* token = strtok(url, "/");
if( token == NULL )
   return -1;
strcpy(ret->protocol, token);
strcat(ret->protocol, "//");

// skip next '/'
token = strtok(NULL, "/");
if( token == NULL )
   return -1;

//get host
token = strtok(NULL, "/");
if( token == NULL )
   return -1;
strcpy(ret->host, token);

// get path
token = strtok(NULL, "#");
if( token == NULL )
   return -1;
strcpy(ret->path, token);

// ...

return 0;
}

Вы можете видеть, что я получил возвращаемое значение, чтобы узнать, успешно ли был выполнен синтаксический анализ.

3
ответ дан 18 December 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: