Почему этот код (malloc) не генерирует повреждение кучи?

#include <iostream>

using namespace std;

struct A
{
int a, b;
};

struct B
{
int a;
};

int main()
{
A * pa = (A *)malloc(sizeof(B));
int c = 5;
pa -> a = 3;
cout << pa -> a << endl;
pa -> b = 0;
cout << pa -> b << endl;
cout << c << endl;
return 0;
}

Я запускаю этот код с VC ++ 2012. Он не генерирует никаких сообщений об ошибках.

Я думаю, что pa -> b получит доступ к памяти блока исходящих. Повреждение кучи должно произойти!
Но на самом деле ничего не произошло в режимах отладки и выпуска.

Но поскольку int c следует сразу за A * pa;
Я думаю, что в памяти, pa -> b получит доступ к int c.

Выход программы:
3
4
5

Кто-нибудь может помочь объяснить это?


Если я добавлю «бесплатно (па);» в конце основной:
+ в режиме отладки это вызовет ОШИБКУ КОРРУПЦИИ.
+ в режиме релиза ничего не происходит.

1

Решение

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

Один из практических способов найти ошибки такого типа — использовать такой инструмент, как Valgrind:

$ valgrind ./a.out
a=3
==37240== Invalid write of size 4
==37240==    at 0x100000E1D: main (test.c:22)
==37240==  Address 0x10001b184 is 0 bytes after a block of size 4 alloc'd
==37240==    at 0x5237: malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==37240==    by 0x100000DD2: main (test.c:19)
==37240==
==37240== Invalid read of size 4
==37240==    at 0x100000E28: main (test.c:23)
==37240==  Address 0x10001b184 is 0 bytes after a block of size 4 alloc'd
==37240==    at 0x5237: malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==37240==    by 0x100000DD2: main (test.c:19)
==37240==

Существуют похожие инструменты для Windows: Есть ли хорошая замена Valgrind для Windows?

1

Другие решения

Повреждение кучи может быть обнаружено только при входе в какую-либо функцию кучи. В этом случае вы вводите функцию кучи только в начале, когда куча все еще не повреждена. Попробуйте удалить структуру, указанную на pa перед возвращением из mainи посмотрим, что получится.

0