Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
#1

Выделение памяти в объектах - C++

20.09.2011, 21:59. Просмотров 447. Ответов 1
Метки нет (Все метки)

Здравствуйте! Когда начал использовать динамическое выделение памяти в объектах, возникла проблема. Но сначала о тестовой программе, которую я написал. Точнее о классе. Я создал класс Vector. Вот Vector.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
class Vector
{
private:
    bool isVector;
    i4 cellLength;
    i4 cellsCount;
    i4 cellsLength;
    void *cells;
    i4 *tempObject;
public:
    Vector(i4 cellsCount, i4 cellLength);
    Vector(i4 cellsCount);
    ~Vector(void);
};
А вот Vector.cpp
C++
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
#include "StdAfx.h"
#include "Vector.h"
#include <malloc.h>
#include "memManager.h"
 
Vector::Vector(i4 cellsCount, i4 cellLength)
{
    isVector=false;
    this->cellLength=cellLength;
    this->cellsCount=cellsCount;
    cellsLength=cellLength*cellsCount;
    if (cellsLength!=0)
    {
        cells=malloc(cellsLength);
        memCopy(0,cells,cellsLength);
    } 
    else
    {
        cells=0;
    }
    
    tempObject=new i4[25000000];
}
 
Vector::Vector(i4 cellsCount)
{
    isVector=true;
    this->cellLength=sizeof(Vector);
    this->cellsCount=cellsCount;
    cellsLength=cellLength*cellsCount;
    if (cellsLength!=0)
    {
        cells=malloc(cellsLength);
    } 
    else
    {
        cells=0;
    }
    Vector *tempVector=(Vector *)cells;
    for (i4 i=0; i<cellsCount; i++)
    {
        *tempVector=Vector(0,0);
        tempVector++;
    }
 
    tempObject=new i4[25000000];
}
 
Vector::~Vector(void)
{
    if (isVector)
    {
        Vector *tempVector=(Vector *)cells;
        for (i4 i=0; i<cellsCount; i++)
        {
            tempVector->~Vector();
            tempVector++;
        }
    }
    if (cells!=0)
    {
        free(cells);
    }   
 
    delete[] tempObject;
}
Да, вот ещё stdafx.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
 
#pragma once
 
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"Shell32.lib")
 
typedef __int8 i1;
typedef __int16 i2;
typedef __int32 i4;
typedef __int64 i8;
 
typedef unsigned __int8 i1Ps;
typedef unsigned __int16 i2Ps;
typedef unsigned __int32 i4Ps;
typedef unsigned __int64 i8Ps;
 
typedef float r4;
typedef double r8;
 
// TODO: reference additional headers your program requires here
и memManager.h
C++
1
void memCopy(void *inMem, void *outMem, i4 length);
и memManager.cpp
C++
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
#include "stdafx.h"
 
void memCopy(void *inMem, void *outMem, i4 length)
{
    if (((outMem!=0)&&(length>=0))||((outMem==0)&&(length==0)))
    {
        i4 i4Count=length/sizeof(i4);
        i4 charCount=length%sizeof(i4);
 
        i4 *i4OutArray=(i4 *)outMem;
        char *charOutArray=(char *)outMem;
        charOutArray+=i4Count*sizeof(i4);
 
        if (inMem!=0)
        {
            i4 *i4InArray=(i4 *)inMem;
            char *charInArray=(char *)inMem;
            charInArray+=i4Count*sizeof(i4);
 
            for (i4 i=0; i<i4Count; i++)
            {
                *i4OutArray=*i4InArray;
                i4InArray++;
                i4OutArray++;
            }
 
            for (i4 i=0; i<charCount; i++)
            {
                *charOutArray=*charInArray;
                charInArray++;
                charOutArray++;
            }
        } 
        else
        {
            for (i4 i=0; i<i4Count; i++)
            {
                *i4OutArray=0;
                i4OutArray++;
            }
 
            for (i4 i=0; i<charCount; i++)
            {
                *charOutArray=0;
                charOutArray++;
            }
        }
    }
    return;
}
В общем, вектор состоит из произвольных ячеек длиной cellLength и количеством cellsCount. Или он состоит из таких-же векторов. И для двух этих случаев предусмотрено два конструктора. В первом передеётся число ячеек и их длина, а во втором передеётся только число ячеек, поскольку длина их известна и равняется sizeof(Vector). На тип вектора указывает флаг isVector.Также в конструкторе захватывается участок памяти размером примерно 100 мб и указатель на него хранится в поле tempObject. В деструкторе этот участок памяти освобождается. Причём в деструкторе используется рекурсия: если вектор состоит ихз векторов, то при удалении вектора нужно удалить и все внутренние вектора. Причём если ветор состоит из векторов, что соответствует второму конструктору, то эти вектора нужно проинициализировать как вектора, состоящие из ячеек нулевой длины нулевого размера. Это нужно потому, что при удалении вектора деструктор по рекурсии запустится и для этих векторов, а если там будет мусор, например флаг isVector будет установлен в true, то это снова вызовет запуск деструктора или cells не будет равен нулю, и деструктор попытается освободить память, которая итак не выделена, что приведёт к ошибке. Вот программа, где я использую Vector:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// TestVector.cpp : main project file.
 
#include "stdafx.h"
#include <iostream>
#include "Vector.h"
#include <malloc.h>
 
using namespace System;
using namespace std;
 
int main(array<System::String ^> ^args)
{
    Vector vect=Vector(3);
    system("pause");
    return 0;
}
Она создаёт вектор, содержащий 3 нулевых вектора. Программа компилируется нормально. Но при выполнении возникает ошибка обращения к защищённой памяти. Когда я запустил отладку, то обнаружил, что при инициализации внутренних векторов (строчка *tempVector=Vector(0,0) происходт выделение памяти (строчка tempObject=new i4[25000000] по одному и тому-же адресу, и при вызове деструктора получается, что память с этим адресом освобождается 3 раза. Почему так происходит, я совсем не понимаю. Ведь при инициализации векторов память должна выделяться для каждого вектора.

Добавлено через 6 минут
Запустив диспетчер задач я убедился, что программа использует памяти 100мб, а должно быть по идее 300мб, даже не 300 а 400, поскольку в каждом вектре болжно выделяться по 100мб, а векторов получается 4: непосредственно вектор vect, и 3 внутренних вектора.

Добавлено через 1 час 11 минут
Ещё я обнаружил, что после вызова конструктора Vector(0,0) в строчке *tempVector=Vector(0,0); почему-то сразу вызывается деструктор ~Vector(). И, получается, что из-за этого и ошибка. То есть деструктор вызывается сразу и при удалении вектора, но почему так происходить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.09.2011, 21:59     Выделение памяти в объектах
Посмотрите здесь:

Выделение памяти C++
C++ выделение памяти
Выделение памяти. C++
C++ Выделение памяти...
C++ выделение памяти
Выделение памяти C++
Выделение памяти C++
C++ Выделение памяти
Выделение памяти C++
C++ Выделение памяти
Выделение памяти(С = С++) C++
Выделение памяти C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт С++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.09.2011, 22:13     Выделение памяти в объектах #2
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
using namespace System;
using namespace std;
int main(array<System::String ^> ^args)
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
#include "stdafx.h"
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
cells=malloc(cellsLength);
тому кто писал код явно чего-то не хватает
Yandex
Объявления
20.09.2011, 22:13     Выделение памяти в объектах
Ответ Создать тему
Опции темы

Текущее время: 00:39. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru