Выделение памяти в dll, передача массива из dll и очистка памяти

227
21 апреля 2017, 21:23

Всем привет есть 2 вопроса:

  1. Корректно ли так очищать память, как в коде если функция calc будет располагаться в отдельной dll? Если нет то как правильно? или есть ли другие варианты?
  2. Почему в аргументах функции calc приходится писать именно ссылку на указатель Test *& test, а не Test * test?

    #include <iostream>
    using namespace std;
    struct Test
    {
       int a;
       int b;
    };
     **// Эта функция будет в dll**
     void calc(Test *& test, unsigned int &sizeTest)
     {
     sizeTest = 3;
     test = new Test[sizeTest];
     for (uint i = 0; i < sizeTest; i++)
     {
     test[i].a = i;
     test[i].b = i;
     }
     }
    
    int main() 
    {
    Test *test = NULL;
    unsigned int sizeTest = 0;
    calc(test, sizeTest);
    cout << sizeTest << endl;
    for (uint i = 0; i < sizeTest; i++)
    {
    cout << test[i].a << endl;
    cout << test[i].b << endl;
    }
    // Корректно ли тут очищать память, выделенную в другой функции?
    delete[] test;
    return 0;
    }
Answer 1
  1. В общем случае так делать нельзя. Можно нарваться на проблемы. Память выделенную в dll надо освобождать в dll. Потому что менеджер памяти у процесса и dll может быть разный. Если так сильно надо выделять память в dll и передавать вызвавшему процессу, то можно в dll предусмотреть и функцию освобождения такой памяти, которую должен будет вызывать процесс.
  2. Указатель - это переменная (ячейка памяти) хранящая адрес другой переменной. Параметры функции - это по сути отдельные переменные, которые создаются для каждого вызова функции, и которым ты присваиваешь значение при её вызове. Поэтому чтобы изменить значение указателя с помощью функции, нужно чтобы параметр был ссылкой на указатель. На самом деле, внутренне, ссылка - это тоже указатель, просто синтаксис работы с ней - как с переменной. То есть когда ты передаешь ссылку на указатель, ты по сути передаешь указатель на указатель. А если ты просто передашь указатель не по ссылке, то ты передашь копию указателя, и эту копию внутри функции и изменишь - присвоишь ей значение адреса выделенной памяти.

Без ссылок ваша функция выглядела бы так:

void calc(Test ** test, uint * sizeTest)
{
   *sizeTest = 3;
   *test = new Test[*sizeTest];
   for (uint i = 0; i < *sizeTest; i++)
   {
       (*test)[i].a = i;
       (*test)[i].b = i;
   }
}
// использование
Test * array = nullptr;
uint   size  = 0;
calc(&array, &size);
READ ALSO
Постоянный посыл сообщения WM_MOUSEMOVE

Постоянный посыл сообщения WM_MOUSEMOVE

ПриветствуюЕсть задача: при движении мыши в окне должен двигаться статик внутри данного окна

244
Подскажите, где ошибка в шаблоне, С++ [дубликат]

Подскажите, где ошибка в шаблоне, С++ [дубликат]

На данный вопрос уже ответили:

199
Записать и считать обьект в файл С++

Записать и считать обьект в файл С++

Здравствуйте, имеется массив обьектов static vector<MobilePhone*> devices;Как можно записать все что внутри в бинарный файл, чтобы при повторном запуске...

209
Двухнаправленный список

Двухнаправленный список

В списке нужно поменять местами второй элемент и максимальныйЯ сделал, но надо упростить код

203