Недопустимое чтение размера 1 в состоянии цикла while - PullRequest
0 голосов
/ 26 февраля 2019

Я недавно унаследовал код, написанный на C, без какой-либо документации.Я работал над ее оптимизацией и исправлением, и я сталкивался с этим.

int  LookBack(char * Start, int Length, char *Ignore)
{
  char  LookBuffer[10];
  //while(Start[-1] && Length--) Start--; // Start[-1]. No idea what that is supposed to mean.
  while(Length > 0 && Start[0]){
    Start--;
    Length--;
  }
  strncpy(LookBuffer, Start, sizeof(LookBuffer));
  if(strcasestr(LookBuffer, Ignore)) {
    return(1);
  }
  return(0);
}

Эта функция используется для определения, находится ли подстрока на определенном расстоянии перед строкой Start.Например, возьмем строку The designation is API RP 5L1, а Start - указатель на API RP 5L1.Итак, если Ignore = "The" и Length = 10, функция вернет 0.

Мой вопрос

Valgrind выдаст мне ошибку Invalid read of size 1, поскольку она читает за выделенную память вwhile(Length > 0 && Start[0]) или так я верю.Можно ли как-нибудь проверить, находится ли Start[0] в выделенной памяти, не сделав неверное чтение?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Функция называется LookBack, поэтому она, кажется, вызывается в некотором процессе обработки / токенизации строк, подобном strtok (), который вставляет немного \0 в точку разделения.

while(Start[-1] && Length--) Start--;Посмотрите на позицию перед Start [0], если она не является символом \0.Если это не \0, вернитесь назад.

while( (*(Start-1) != '\0') && (0 != (Length--))) Start--;

Итак, после цикла while вы фактически получаете указатель «start» в строке, переданной указателем Start, без перенастройки его на +1, чтобы фактически получить вторую часть строки.

При замене вы фактически пропускаете продвижение указателя Start после этого, потому что теперь он указывает на \0, который завершает строку, поэтому ваши строковые функции будут просто видеть строку strlen (Start) = 0.

0 голосов
/ 26 февраля 2019

Для функций C, работающих с буферами памяти, ответственность за передачу допустимых указателей лежит на вызывающей стороне.Там может быть какой-то специфический для платформы прием, но с точки зрения стандартного C это невозможно, как и для многих платформ (например, только что освобожденная память часто неотличима от все еще выделенной).

...