Почему mprobe терпит неудачу при проверке строковых литералов? - PullRequest
0 голосов
/ 30 сентября 2019

Чтобы обеспечить функциональную целостность структуры данных, которую я реализовал, я написал тестовый файл, используя mcheck, чтобы убедиться, что я работаю в пределах выделенной памяти. Однако, пытаясь использовать mprobe() в строковом литерале (и вызывая mcheck(NULL) в начале), программа всегда прерывается с MCHECK_HEAD.

Я пробовал это с самой маленькой программой, которую я могу представить:

#include <mcheck.h>
#include <stdio.h>

int main()
{

    mcheck(NULL);
    mprobe("test");

    exit(0);

}

В результате получается следующее:

$ gcc test.c -lmcheck
$ ./a.out
memory clobbered before allocated block
Aborted (core dumped)

Таким образом, кажется, что mcheck завершается сбоем всякий раз, когда сталкивается со строковым литералом, думая, что предыдущая память была изменена. Почему? Это потому, что строка явно не malloc ed?

1 Ответ

5 голосов
/ 30 сентября 2019
enum mcheck_status mprobe(void *ptr);

[...]

Функция mprobe() выполняет проверку согласованности блока выделенной памяти, на который указывает ptr.

Строковый литерал не является указателем на выделенную память. Стандарт C очень строго определяет выделенное хранилище как то, которое выделено с помощью malloc, calloc, realloc и т.п. POSIX расширяет список, например, strdup. Строковый литерал, с другой стороны, является неизменяемым массивом символов со статической продолжительностью хранения, хотя у него нет типа элемента const, поэтому вы не получили предупреждение. Попробуйте:

char *foo = "test";
const char *bar = "test";
mprobe(foo);
mprobe(bar);

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

<source>: In function 'main':
<source>:12:12: warning: passing argument 1 of 'mprobe' discards 'const' qualifier
from pointer target type [-Wdiscarded-qualifiers]
   12 |     mprobe(bar);
      |            ^~~
In file included from <source>:1:
/usr/include/mcheck.h:53:41: note: expected 'void *' but argument is of
type 'const char *'
   53 | extern enum mcheck_status mprobe (void *__ptr) __THROW;
      |                                   ~~~~~~^~~~~
...