Создать/удалить[] и VirtualAlloc

#include <Windows.h>
#include <iostream>

using namespace std;

int main(void)
{
    unsigned char* pFoo = new unsigned char[1000];

    pFoo = (unsigned char*)VirtualAlloc(NULL, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    VirtualFree(pFoo, 0, MEM_RELEASE);

    delete[] pFoo;

    cin.ignore();
    cin.get();

    return 0;
}

Это падает для меня в

delete[] pFoo;

Я знаю, что это происходит из-за VirtualAlloc, но я не знаю, как это исправить...


person replicant    schedule 10.10.2011    source источник


Ответы (3)


Вы используете одну и ту же переменную. Итак, ваше первое распределение просочилось.

После того, как вы освободите его с помощью VirtualFree, указатель станет недействительным. Итак, delete на нем не определено.

Более того:

Вы не можете смешивать VirtualAlloc и delete по той же причине, по которой вы не можете смешивать malloc с delete.

person Mysticial    schedule 10.10.2011
comment
Так что просто VirtualFree(pFoo, 0, MEM_RELEASE); достаточный? - person replicant; 10.10.2011
comment
Что ж, основная проблема в том, что у вас есть два разных выделения памяти для одной и той же переменной. Второе выделение перезапишет указатель из первого. Затем вы пытаетесь освободить/освободить его дважды. - person Mysticial; 10.10.2011
comment
Не могли бы объяснить, чего вы пытаетесь достичь с помощью двух распределений? А может вы что-то не так понимаете? - person Mysticial; 10.10.2011
comment
Спасибо! Я понимаю, новое сейчас не нужно. - person replicant; 10.10.2011

unsigned char* pFoo = new unsigned char[1000];

Теперь pFoo содержит указатель на динамическую память.

pFoo = (unsigned char*)VirtualAlloc(NULL, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

Это перезаписывает старый указатель, происходит утечка массива 1000 char.

Пытаться:

unsigned char* pFoo = new unsigned char[1000];
unsigned char* pBar = (unsigned char*)VirtualAlloc(NULL, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
VirtualFree(pBar, 0, MEM_RELEASE);
delete[] pFoo;
person Ben Voigt    schedule 10.10.2011

Либо используйте new/delete, либо VirtualAlloc/VirtualFree. Вы выделяете два отдельных блока памяти, используя pFoo для обращения к обоим (когда, конечно, он может обращаться только к одному за раз), а затем вызываете две свободные функции с помощью pFoo. Один из них провалится :)

person Graham Perks    schedule 10.10.2011