Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Структуры, динамические массивы и автоматическое освобождение памяти. / 8 сообщений из 8, страница 1 из 1
14.01.2013, 23:45
    #38110110
Zalizo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
Доброго времени суток. Дико извиняюсь, если подобный вопрос уже обсуждался, но я всё-же не нашёл ответа по своему вопросу и искренне надеюсь на помощь знающих людей, т.к. уже ничего в голову не лезет.
Как можно автоматизировать освобождение памяти динамического массива в структуре? Пробовал баловаться с деструктором, но при работе с функциями, работающими с данными структурами получаем небольшую проблему в виде вызова нескольких деструкторов, в следствии чего разрушение динамического массива.
Чтобы было понятнее вот программа-пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
#include <cstdlib>
#include <stdio.h>
#include <string.h>

using namespace std;

struct Test
{
private:
    char * Array;
    int ArraySize;
public:
    Test()
    {
        ArraySize = 0;
    }
    ~Test()
    {
        FreeArray();
    }

    void SetArray(const char buffer_in[], int bufferSize)
    {
        FreeArray();
        if(bufferSize > 0)
        {
            ArraySize = bufferSize;
            Array = new char[ArraySize];
            memcpy(Array, buffer_in, ArraySize);
        }
    }
    void GetArray(char * buffer_out, int bufferSize)
    {
        if(bufferSize > 0)
        {
            memset(buffer_out, 0, bufferSize);
            if(ArraySize>0)
            {
                int copyLen = ArraySize > bufferSize ? bufferSize : ArraySize;
                memcpy(buffer_out, Array, copyLen);
            }
        }
    }
    void FreeArray()
    {
        if(ArraySize>0)
        {
            delete [] Array;
        }
        ArraySize = 0;
    }
};

void TestFunction(Test test)
{
    char buffer[1024];
    test.GetArray(buffer, 1024);
    printf("%s \n", buffer);
}

int main(int argc, char** argv) {

    Test test_s;

    test_s.SetArray("TEST DATA\0", 10);
    printf(" 1th call \n");
    TestFunction(test_s);
    printf(" 2th call \n");
    TestFunction(test_s);
    printf(" end \n");
    return 0;
}



на выходе получаем вылет программы ввиду попытки удаления уже удалённого массива:
1th call
TEST DATA
2th call
фХ#aфХ#a

ВЫПОЛНЕНИЕ FAILED (значение выхода 1,, общее время: 2s)


Буду благодарен за лубую помощь в данном вопросе. Заранее спасибо.
...
Рейтинг: 0 / 0
14.01.2013, 23:49
    #38110116
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
ZalizoБуду благодарен за лубую помощь в данном вопросе. Заранее спасибо.конструктор копирования в классе спасёт отца русской демократии.
Да и по константной ссылке лучше классы в функции передавать то
Код: plaintext
1.
2.
3.
4.
void TestFunction( const Test &test )
{
   ...
}
...
Рейтинг: 0 / 0
15.01.2013, 00:14
    #38110139
Zalizo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
Огромнейшее человеческое спасибо. Всё заработало.
Сделал так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

using namespace std;

struct Test
{
private:
    char * Array;
    int ArraySize;
public:
    Test()
    {
        ArraySize = 0;
    }
    ~Test()
    {
        FreeArray();
    }
    Test(const Test & _t){
        ArraySize = 0;
        _t.Clone(this);
    }
    void Clone(Test * t) const
    {
        t->SetArray(Array, ArraySize);
    }
    void SetArray(const char buffer_in[], int bufferSize)
    {
        FreeArray();
        if(bufferSize > 0)
        {
            ArraySize = bufferSize;
            Array = new char[ArraySize];
            memcpy(Array, buffer_in, ArraySize);
        }
    }
    void GetArray(char * buffer_out, int bufferSize)
    {
        if(bufferSize > 0)
        {
            memset(buffer_out, 0, bufferSize);
            if(ArraySize>0)
            {
                int copyLen = ArraySize > bufferSize ? bufferSize : ArraySize;
                memcpy(buffer_out, Array, copyLen);
            }
        }
    }
    void FreeArray()
    {
        if(ArraySize>0)
        {
            delete [] Array;
        }
        ArraySize = 0;
    }
};

void TestFunction(Test test)
{
    char buffer[1024];
    test.GetArray(buffer, 1024);
    printf("%s \n", buffer);
}

int main(int argc, char** argv) {

    Test test_s;

    test_s.SetArray("12345678901234567890", 10);
    for(int i1=0;i1<1000000;i1++)
    {
        printf(" %d call \n", i1);
        TestFunction(test_s);
        usleep(50 * 1000);
    }
    printf(" end \n");
    return 0;
}




Также послушаюсь совета и подробнее пощупаю константные ссылки для передачи в функции.
...
Рейтинг: 0 / 0
15.01.2013, 01:51
    #38110183
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
Zalizo, обрати внимание на это ещё: 13720886 , да и всю ту тему почитай, там есть то, что тебе пригодится
...
Рейтинг: 0 / 0
15.01.2013, 02:33
    #38110193
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
egorych,

Лучше сразу сюда . См там пример кода в разделе A successful solution

Там приведен более корректный код для swap с учетом некоторых практических нюансов.
...
Рейтинг: 0 / 0
15.01.2013, 09:27
    #38110264
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
Anatoly Moskovsky, они там сделали swap свободной функцией, а не членом класса, имеет ли это значение? или это исключительно вопрос личных предпочтений?
...
Рейтинг: 0 / 0
15.01.2013, 14:51
    #38110759
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
egorych,

Там два приема:
1) внутри реализации swap применен using std::swap и неквалифицированный вызов swap для полей
2) swap - свободная функция

Это решает следующие задачи.
1 позволяет для вложенных полей применять swap описанный в неймспейсе где описан класс поля, который может быть оптимальнее чем std::swap (а иногда и единственно возможный)
2 позволяет сам текущий класс применять в качестве вложенного поля в других классах с такой же организацией копирования через неквалифицированный swap
...
Рейтинг: 0 / 0
15.01.2013, 20:31
    #38111421
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Структуры, динамические массивы и автоматическое освобождение памяти.
Anatoly Moskovsky, спасибо за разъяснения.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Структуры, динамические массивы и автоматическое освобождение памяти. / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]