2015-05-23 5 views
0

У меня есть следующий вопрос. Я не, если это возможно и как. Я хочу понять, когда код использует адрес памяти, выделенный в кучу (для всех типов встроенных объектов и определения пользователя). Например:C++ как проверить доступ к памяти кучи

char* p= new char[60]; 
strcpy(p,"home"); // statement A 

Существует способ, чтобы понять, что «утверждение А», используя адрес «р», выделенную в куче? Переопределяя оператор new, я могу сохранить адреса кучи, но как понять, когда некоторые инструкции их используют? Я хотел бы сделать это прозрачным способом для пользователя.

Большое спасибо

****** Пример

char* p= new char[60]; 
delete [] p; 
strcpy(p,"home"); // statement A 

Я хочу предупредив этот неверный доступ к памяти. Для этого я должен понимать, что strcpy пытается получить доступ к адресу p, поэтому я могу выполнить некоторый тест на достоверность p.

+0

Что именно вы подразумеваете под «как понимать, когда некоторые инструкции используют их»? Я не понимаю, чего вы пытаетесь достичь. – Mat

+0

Привет, Mat, я хочу понять, когда программа использует адрес для чтения/записи. – GTA

+0

Что значит «понимать» здесь? Или что вы не понимаете в заявлении A? Есть ли другие утверждения, которые вы не получаете? – Mat

ответ

1

Посмотрите: http://www.hboehm.info/gc/gcdescr.html Это прозрачный сборщик мусора для C/C++. Он отслеживает то, что указатели существуют ссылки на ячейки памяти так, как вы описали:

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

Регистры. В зависимости от архитектуры это может быть сделано с использованием ассемблерного кода или вызовом функции setjmp-like, которая сохраняет содержимое регистра в стеке . Стек (ы). В случае однопоточного приложения на большинстве платформ это делается , сканируя память между (аппроксимацией) текущего стека указателем и GC_stackbottom. (Для Itanium, стек регистра сканировал отдельно.) Переменная GC_stackbottom установлена ​​в режиме высокой скорости , в зависимости от соответствующей конфигурации информации в gcconfig.h. Обратите внимание, что текущему активному стеку необходимо тщательно отслеживать , так как регистры сохранения кода клиентского кода могут отображаться внутри кадров стопки коллектора, которые могут меняться во время процесса маркировки . Это устраняется путем сканирования некоторых разделов стека «с нетерпением», эффективно фиксируя моментальный снимок в один момент времени.

Статические данные (ы). В простейшем случае это область между DATASTART и DATAEND, как определено в gcconfig.h. Однако в большинстве случаев это касается также областей статических данных, связанных с динамическими библиотеками . Они идентифицируются главным образом кодом платформы в dyn_load.c.

Маркер поддерживает явный стек областей памяти, которые, как известно, должны быть доступны, но до сих пор не искали содержатся указатели. Каждая запись стека содержит начальный адрес проверяемого блока, а также дескриптор блока.Если для блока доступно , то дескриптор имеет длину . (Для других возможностей, см gc_mark.h.)

Как вы можете себе представить, вы должны действительно закатить рукава и сделать некоторое чрезвычайно хаки низкоуровневого управлять этим, и это дорогая вещь для сканирования так что я не думаю, что вы можете сделать это по соображениям безопасности против оборванных указателей.

Я бы рекомендовал не пытаться сделать это так прозрачно. Получили ли пользователи ручки на ваши объекты, такие как умные указатели, и станет намного проще навязывать сбор мусора или безопасность против оборванных указателей или что угодно. C++ выделяется в таких полупрозрачных решениях, где вы можете создавать объекты, которые чувствуют себя как указатели, и предлагать одни и те же операторы, но делать то, что вам нужно больше.

1

Вопрос не имеет смысла. Strcpy считает, что указатель указывает на действительную память, поэтому вам не нужно ничего знать здесь. Если вы хотите утверждать, что память действительна, используйте класс, который позаботится об этом. Тогда вы всегда можете знать, что память действительна.

В этом случае std :: string будет правильным выбором, например std :: vector или std :: shared_ptr.