Как проверить, доступен ли определенный адрес памяти для использования в c ++? - PullRequest
4 голосов
/ 04 июля 2019

Я работаю над своим хобби-проектом на c ++ и хочу проверить непрерывное распределение памяти для переменных разных типов (например, массив с переменными разных типов).Как я могу проверить, доступен ли конкретный адрес памяти для использования?

Подробнее:

Допустим, у нас есть следующий код: у нас есть целое число int_var, (не имеет значения, в каком адресе памяти находится эта переменная), чтобы выделить переменную другого типа в адресе сразу после адреса int_var, мне нужно проверить, доступен ли этот адрес, и затем использоватьЭто.я попробовал следующий код:

int int_var = 5;
float* flt_ptr = (float*)(&int_var + (sizeof(int_var) / sizeof(int)));
// check if flt_ptr is successfully allocated
if (flt_ptr) { // successfully allocated
    // use that address
} else { // not successfully allocated
    cout << "ERROR";
}

Проблема в том, что: Когда я запускаю программу, иногда flt_ptr успешно распределяется и все в порядке, а иногда нет - но когда он не распределяется успешно, выдаетисключение, которое говорит «Нарушение прав чтения ...» вместо печати "ERROR".Это почему?Может быть, я что-то упустил из проверки, если flt_ptr успешно выделен?Или сделал что-то не так?Если так, как я могу проверить, успешно ли выделен flt_ptr, прежде чем я его использую?

Спасибо !!

Ответы [ 4 ]

4 голосов
/ 04 июля 2019

Предполагается, что эта модель памяти действительна еще в DOS, где в реальном режиме память представляла собой непрерывный поток байтов.

Теперь, когда у нас есть пейджинг (или в x86, или в x64), это невозможно. Следовательно, вы не можете делать предположений о существовании памяти «рядом» с памятью.

Вы должны правильно распределиться, что означает использование C ++ shared_ptr / unique_ptr / STL. Или new / malloc по старому (плохому) пути.

Если вы хотите, чтобы переменные находились рядом друг с другом, выделите всю память сразу (например, через структуру).

2 голосов
/ 04 июля 2019

Вы не можете, модель памяти C ++ не работает так.

Единственными действительными указателями являются те, которые получены оператором &, возвращаемые из new / malloc и статических массивов. Не существует механизма для проверки, является ли адрес памяти (все еще) действительным или объект был уничтожен или вообще не существовал там. Так что программист должен управлять правильностью указателей.

По указанным выше причинам ваша программа имеет неопределенное поведение.

if(pointer) только проверяет, является ли pointer==0, не более того. Обратите внимание, что int n=5; int array[n]; также не является допустимым C ++. Не уверен, что вы используете его, но если вы это делаете, не надо.

Основываясь на комментариях, вы хотите гетерогенный контейнер. В этом случае используйте массив союзов или лучше std::array<std::variant<int,double,char, float...>> array;. Или std::vector, если вам нужен динамический размер.

C ++ гарантирует, что массивы ([], malloc или new[]) являются смежными, но они содержат только один тип. Как правило, вы не можете хранить float, double, int, char непрерывно вместе из-за проблем с выравниванием. Выше array является непрерывным с точки зрения объекта std::variant, но его размер будет, по крайней мере, размером самого большого типа. Так что chars не будет упакован вместе.

1 голос
/ 04 июля 2019

хочу проверить непрерывное выделение памяти для переменных разные типы

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

Например:

struct eg_struct
{
           unsigned char abc;
           unsigned int  xyz;
}

Обратите внимание, что при необходимости вам может понадобиться упаковать структуру.

Здесь нет необходимости проверять, свободна ли память или нет.

1 голос
/ 04 июля 2019

Это не то, как вы распределяете память.Вы должны сделать это правильно, используя new.

См. здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...