Как работает функция realloc, передавшая в качестве аргумента нулевой размер?
со страницы руководства:
Если ptr не имеет значения NULL, он должен
возвращаться функцией более ранний вызов malloc(), calloc() или realloc().
Почему это нужно?
скомпилируйте это с gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 без опций(флагов)
этот пример
#include
int main () {
int *p = malloc(0);
p = realloc(p, 0);
return 0;
}
это рабочий код, проверка памяти с помощью valgrind показывает это:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==185872== Memcheck, a memory error detector
==185872== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==185872== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==185872== Command: ./test
==185872==
==185872==
==185872== HEAP SUMMARY:
==185872== in use at exit: 0 bytes in 0 blocks
==185872== total heap usage: 1 allocs, 1 frees, 0 bytes allocated
==185872==
==185872== All heap blocks were freed -- no leaks are possible
==185872==
==185872== For lists of detected and suppressed errors, rerun with: -s
==185872== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from
но затем скомпилируйте это (добавлен флаг -g):
#include
int main () {
int *p = NULL;
p = realloc(p, 0);
return 0;
}
Вывод valgrind показывает ошибки (утечка памяти):
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==186749== Memcheck, a memory error detector
==186749== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==186749== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==186749== Command: ./test
==186749==
==186749==
==186749== HEAP SUMMARY:
==186749== in use at exit: 0 bytes in 1 blocks
==186749== total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==186749==
==186749== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==186749== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749== by 0x10916D: main (test1.c:5)
==186749==
==186749== LEAK SUMMARY:
==186749== definitely lost: 0 bytes in 1 blocks
==186749== indirectly lost: 0 bytes in 0 blocks
==186749== possibly lost: 0 bytes in 0 blocks
==186749== still reachable: 0 bytes in 0 blocks
==186749== suppressed: 0 bytes in 0 blocks
==186749==
==186749== For lists of detected and suppressed errors, rerun with: -s
==186749== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
почему это происходит, даже если я ничего не выделил?
редактирует:
скомпилировал это с помощью -std=c11 -g:
р>
#include
#include
#include
#define ASSERT_ERROR_PREFIX "Assertion "
#define ASSERT_ERROR_SUFFIX " failed\n"
#define assert(x, num) { \
if(!(x)) { \
write(STDOUT_FILENO, ASSERT_ERROR_PREFIX, strlen(ASSERT_ERROR_PREFIX)); \
write(STDOUT_FILENO, num, sizeof(char)); \
write(STDOUT_FILENO, ASSERT_ERROR_SUFFIX, strlen(ASSERT_ERROR_SUFFIX)); \
} \
}
int main () {
int *p = NULL;
p = realloc(p, 0);
*p = '1';
assert((*p == '1'), "1");
assert((p == NULL), "2");
return 0;
}
вывод: утверждение 2 не выполнено
вывод valgrind:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==190041== Memcheck, a memory error detector
==190041== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==190041== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==190041== Command: ./test
==190041==
==190041== Invalid write of size 4
==190041== at 0x109196: main (test1.c:19)
==190041== Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
==190041== Invalid read of size 4
==190041== at 0x1091A0: main (test1.c:20)
==190041== Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
Assertion 2 failed
==190041==
==190041== HEAP SUMMARY:
==190041== in use at exit: 0 bytes in 1 blocks
==190041== total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==190041==
==190041== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
==190041== LEAK SUMMARY:
==190041== definitely lost: 0 bytes in 1 blocks
==190041== indirectly lost: 0 bytes in 0 blocks
==190041== possibly lost: 0 bytes in 0 blocks
==190041== still reachable: 0 bytes in 0 blocks
==190041== suppressed: 0 bytes in 0 blocks
==190041==
==190041== For lists of detected and suppressed errors, rerun with: -s
==190041== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Подробнее здесь: https://stackoverflow.com/questions/793 ... s-argument
Как работает realloc, в качестве аргумента передан размер 0 ⇐ Linux
-
Anonymous
1736249341
Anonymous
Как работает функция realloc, передавшая в качестве аргумента нулевой размер?
со страницы руководства:
Если ptr не имеет значения NULL, он должен
возвращаться функцией более ранний вызов malloc(), calloc() или realloc().
Почему это нужно?
скомпилируйте это с gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 без опций(флагов)
этот пример
#include
int main () {
int *p = malloc(0);
p = realloc(p, 0);
return 0;
}
это рабочий код, проверка памяти с помощью valgrind показывает это:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==185872== Memcheck, a memory error detector
==185872== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==185872== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==185872== Command: ./test
==185872==
==185872==
==185872== HEAP SUMMARY:
==185872== in use at exit: 0 bytes in 0 blocks
==185872== total heap usage: 1 allocs, 1 frees, 0 bytes allocated
==185872==
==185872== All heap blocks were freed -- no leaks are possible
==185872==
==185872== For lists of detected and suppressed errors, rerun with: -s
==185872== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from
но затем скомпилируйте это (добавлен флаг -g):
#include
int main () {
int *p = NULL;
p = realloc(p, 0);
return 0;
}
Вывод valgrind показывает ошибки (утечка памяти):
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==186749== Memcheck, a memory error detector
==186749== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==186749== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==186749== Command: ./test
==186749==
==186749==
==186749== HEAP SUMMARY:
==186749== in use at exit: 0 bytes in 1 blocks
==186749== total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==186749==
==186749== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==186749== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749== by 0x10916D: main (test1.c:5)
==186749==
==186749== LEAK SUMMARY:
==186749== definitely lost: 0 bytes in 1 blocks
==186749== indirectly lost: 0 bytes in 0 blocks
==186749== possibly lost: 0 bytes in 0 blocks
==186749== still reachable: 0 bytes in 0 blocks
==186749== suppressed: 0 bytes in 0 blocks
==186749==
==186749== For lists of detected and suppressed errors, rerun with: -s
==186749== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
почему это происходит, даже если я ничего не выделил?
редактирует:
скомпилировал это с помощью -std=c11 -g:
р>
#include
#include
#include
#define ASSERT_ERROR_PREFIX "Assertion "
#define ASSERT_ERROR_SUFFIX " failed\n"
#define assert(x, num) { \
if(!(x)) { \
write(STDOUT_FILENO, ASSERT_ERROR_PREFIX, strlen(ASSERT_ERROR_PREFIX)); \
write(STDOUT_FILENO, num, sizeof(char)); \
write(STDOUT_FILENO, ASSERT_ERROR_SUFFIX, strlen(ASSERT_ERROR_SUFFIX)); \
} \
}
int main () {
int *p = NULL;
p = realloc(p, 0);
*p = '1';
assert((*p == '1'), "1");
assert((p == NULL), "2");
return 0;
}
вывод: утверждение 2 не выполнено
вывод valgrind:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==190041== Memcheck, a memory error detector
==190041== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==190041== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==190041== Command: ./test
==190041==
==190041== Invalid write of size 4
==190041== at 0x109196: main (test1.c:19)
==190041== Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
==190041== Invalid read of size 4
==190041== at 0x1091A0: main (test1.c:20)
==190041== Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
Assertion 2 failed
==190041==
==190041== HEAP SUMMARY:
==190041== in use at exit: 0 bytes in 1 blocks
==190041== total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==190041==
==190041== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==190041== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041== by 0x10918D: main (test1.c:18)
==190041==
==190041== LEAK SUMMARY:
==190041== definitely lost: 0 bytes in 1 blocks
==190041== indirectly lost: 0 bytes in 0 blocks
==190041== possibly lost: 0 bytes in 0 blocks
==190041== still reachable: 0 bytes in 0 blocks
==190041== suppressed: 0 bytes in 0 blocks
==190041==
==190041== For lists of detected and suppressed errors, rerun with: -s
==190041== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Подробнее здесь: [url]https://stackoverflow.com/questions/79332939/how-realloc-works-passed-0-size-as-argument[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия