Проблема с обнаружением ошибки в программе при использовании valgrind - PullRequest
0 голосов
/ 28 февраля 2020

У меня проблема с моей программой. Я использую valgrind, но не могу найти, где проблема. Что я могу изменить в коде. Вот ошибка в valgrind:

==14892== Invalid read of size 1
==14892==    at 0x4C32D44: __strlen_sse2 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14892==    by 0x4EBC9D1: puts (ioputs.c:35)
==14892==    by 0x10878D: main (uloha2.c:10)
==14892==  Address 0x522d04c is 0 bytes after a block of size 12 alloc'd
==14892==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14892==    by 0x1087D2: reverse (uloha2.c:19)
==14892==    by 0x10877D: main (uloha2.c:9)
==14892==
!DLROW OLLEH
==14892==
==14892== HEAP SUMMARY:
==14892==     in use at exit: 0 bytes in 0 blocks
==14892==   total heap usage: 2 allocs, 2 frees, 1,036 bytes allocated
==14892==
==14892== All heap blocks were freed -- no leaks are possible
==14892==
==14892== For counts of detected and suppressed errors, rerun with: -v
==14892== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

А вот часть моего кода, где может быть ошибка.

int main(){
  char* reversed = reverse("Hello world!");
  printf("%s\n", reversed);
  free(reversed);
}

char* reverse(const char* text){
  if(text==NULL){
    return NULL;
  }

  char *novy=(char*)malloc(strlen(text));
  for(int j=0;j<strlen(text);j++){
    novy[j]=toupper(text[j]);
  }

 int p=strlen(text)-1;
 int size=strlen(text); 

 for(int i=0;i<(size/2);i++){
    char tmp=novy[i];
    novy[i]=novy[p];
    novy[p]=tmp;
    p--;
  }

  return novy;
} 

1 Ответ

3 голосов
/ 28 февраля 2020

Вы забываете, что в C все char строки действительно называются завершенными нулями байтовыми строками . Значение с нулевым символом в конце важно, и будет использоваться для поиска конца строк (например, strlen).

Если пропущены строки, функции go выйдут из границы, и у вас будет неопределенное поведение .

Терминатор с нулем - это символ '\0', и важно также помнить, что он не считается сам по себе strlen и что ему нужно место в создаваемой вами строке:

char *novy = malloc(strlen(text) + 1);  // +1 to make room for the terminator

Конечно, вам также нужно скопировать этот терминатор:

for(int j = 0; j <= strlen(text); j++) {
    novy[j] = toupper(text[j]);
}

Обратите внимание на использование less - чем или равный оператор в состоянии l oop. Это обеспечит копирование терминатора.

...