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

Функция для перевыделения памяти для массива - C++

Восстановить пароль Регистрация
 
satisfactor
0 / 0 / 0
Регистрация: 11.01.2010
Сообщений: 51
19.07.2014, 22:44     Функция для перевыделения памяти для массива #1
Доброго времени суток, пишу шаблонный класс для массива и никак не могу разобраться с динамическим перевыделением памяти посредством new && delete. Вот как я попытался это сделать:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <class T>
void arrayM<T>::resize( int number ) {
    assert( number >= 0 );
    T* tmp;
    if ( number == 0 ) {
        if ( data != NULL ) {
            delete [] data;
            data = NULL;
        }
    } else {
        tmp = new T[number];
        if ( data != NULL ) {
            for ( int i = 0; i < size && i < number; i++ ) {
                tmp[i] = data[i];
            }
        }
        std::swap( data, tmp );
    }
    size = number;
    if ( tmp != NULL ) {
        delete [] tmp; //вызывает срабатывание точки останова
    }
}

где последний delete [] вызывает срабатывание точки останова. Программа-тестер:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "arrayM.h"
#include "triangle.h"
 
int main ( void )
{
    point A( 0, 0 );
    point B( 3, 0 );
    point C( 0, 4 );
    triangle a( A, B, C );
 
    arrayM<point> points;
    points.addElement(A);
    points.addElement(B);
    points.addElement(C);
 
    std::cout << a.getPerimeter();
    std::cin.get(); std::cin.get();
    return 0;
}


Точка останова срабатывает при выполнении points.addElement(B);

Интерфейс класса:
Кликните здесь для просмотра всего текста
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
template <class T>
class arrayM {
public:
    //overload
    T& operator[] ( int );
    T& operator[] ( int ) const;
    T& operator= ( const T &reference );
    //constructors
    arrayM( void );
    arrayM( const arrayM< T > & reference );
    //add
    void addElement( const T& reference );
    //delete
    void deleteByIndex( int );
    //search
    int searchElement( const T& reference ) const;
    //get
    int getSize( void ) const;
    //another
    std::ostream & show( std::ostream & = std::cout, char = std::cout.fill() );
    //destructor
    ~arrayM();
private:
    //service
    void resize( int number );
    T* data;
    int size;
};
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.07.2014, 22:44     Функция для перевыделения памяти для массива
Посмотрите здесь:

C++ нехватает памяти для массива
Выделение памяти для массива через функцию и использование этого массива C++
Выделение памяти для массива C++
Выделение памяти для массива C++
Выделение памяти для массива C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11823 / 6802 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
19.07.2014, 22:50     Функция для перевыделения памяти для массива #2
где конструктор, конструктор копий и оператор присваивания?
C++
1
2
    assert( number >= 0 );
    T* tmp = nullptr ;//Указатель "занулите"
satisfactor
0 / 0 / 0
Регистрация: 11.01.2010
Сообщений: 51
19.07.2014, 22:56  [ТС]     Функция для перевыделения памяти для массива #3
Цитата Сообщение от Croessmah Посмотреть сообщение
где конструктор, конструктор копий и оператор присваивания?
Вот:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//constructors
//  constructor by default
template <class T>
arrayM<T>::arrayM( void ) {
    size = 0;
    data = NULL;
}
//  constructor by reference
template <class T>
arrayM<T>::arrayM( const arrayM<T> &reference ) {
    size = reference.size;
    if ( size == 0 )
        data = NULL;
    else {
        data = new T[size];
        //copy elements
        for ( int i = 0; i < reference.size; i++ ) {
            data[i] = reference.data[i];
        }
    }
}
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.07.2014, 01:41     Функция для перевыделения памяти для массива #4
судя по интерфейсу массив предполагается расширяемый, значит эффективнее выделять память заранее чтоб не перераспределять при каждом чихе
satisfactor
0 / 0 / 0
Регистрация: 11.01.2010
Сообщений: 51
20.07.2014, 01:45  [ТС]     Функция для перевыделения памяти для массива #5
Цитата Сообщение от Jupiter Посмотреть сообщение
судя по интерфейсу массив предполагается расширяемый, значит эффективнее выделять память заранее чтоб не перераспределять при каждом чихе
Я понимаю, но сейчас вопрос стоит не в эффективности, а в том, что это даже не работает пока корректно. МНе бы понять что я не верно делаю...
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.07.2014, 02:26     Функция для перевыделения памяти для массива #6
satisfactor, выкладывайте весь код
satisfactor
0 / 0 / 0
Регистрация: 11.01.2010
Сообщений: 51
20.07.2014, 08:48  [ТС]     Функция для перевыделения памяти для массива #7
Цитата Сообщение от Jupiter Посмотреть сообщение
satisfactor, выкладывайте весь код
Кликните здесь для просмотра всего текста
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#pragma once
#include <cstdlib>
#include <cassert>
#include <iostream>
 
template <class T>
class arrayM {
public:
    //overload
    T& operator[] ( int );
    T& operator[] ( int ) const;
    T& operator= ( const T &reference );
    //constructors
    arrayM( void );
    arrayM( const arrayM< T > & reference );
    //add
    void addElement( const T& reference );
    //delete
    void deleteByIndex( int );
    //search
    int searchElement( const T& reference ) const;
    //get
    int getSize( void ) const;
    //another
    std::ostream & show( std::ostream & = std::cout, char = std::cout.fill() );
    //destructor
    ~arrayM();
private:
    //service
    void resize( int number );
    T* data;
    int size;
};
 
//overload
//  overload []
template < class T >
T& arrayM<T>::operator[] ( int index ) {
    assert( index >= 0 && index < size );
    return data[index];
}
//  overload [] const
template < class T >
T& arrayM<T>::operator[] ( int index ) const {
    assert( index >= 0 && index < size );
    return data[index];
}
//  overload =
template <class T>
T& arrayM<T>::operator= ( const T &reference ) {
    if( this == &right ) {
        return *this;
    }
    resize( reference.size );
    for ( int i = 0; i < size; ++i )
        data[i] = reference.data[i];
    return *this;
}
//  overload <<
template < class T >
std::ostream & operator<< ( std::ostream &output, arrayM<T> &reference ) {
    return (reference.show( output, output.fill() ) );
}
 
//constructors
//  constructor by default
template <class T>
arrayM<T>::arrayM( void ) {
    size = 0;
    data = NULL;
}
//  constructor by reference
template <class T>
arrayM<T>::arrayM( const arrayM<T> &reference ) {
    size = reference.size;
    if ( size == 0 )
        data = NULL;
    else {
        data = new T[size];
        //copy elements
        for ( int i = 0; i < reference.size; i++ ) {
            data[i] = reference.data[i];
        }
    }
}
//add
//  addElement
template <class T>
void arrayM<T>::addElement( const T &reference ) {
    resize( size + 1 );
    data[size] = reference;
}
 
//delete
//  deleteByIndex
template <class T>
void arrayM<T>::deleteByIndex( int index ) {
    assert( index >= 0 );
    if (size > 0) {
        assert( index < size );
        for ( int i = index; i < size-1; i++ ) {
            data[i] = data[i+1];
        }
        resize( size-1 );
    }
}
 
//search
//  searchElement
template <class T>
int arrayM<T>::searchElement( const T &reference ) const {
    for (int i = 0; i < size; ++i)
        if ( data[i] == reference )
            return i;
    return -1;
}
 
//get
//  getSize
template <class T>
int arrayM<T>::getSize( void ) const {
    return size;
}
 
//another
//  show
template <class T>
std::ostream & arrayM<T>::show( std::ostream & output, char c ) {
    for ( int i = 0; i < size; i++ )
        if ( i < size - 1 )
            output << data[i] << space;
        else
            output << data[i];
}
 
//destructor
template <class T>
arrayM<T>::~arrayM() {
    delete [] data;
}
 
//service
//  resize: don't use in constructors!
template <class T>
void arrayM<T>::resize( int number ) {
    assert( number >= 0 );
    T* tmp = nullptr;
    if ( number == 0 ) {
        if ( data != NULL ) {
            delete [] data;
            data = NULL;
        }
    } else {
        tmp = new T[number];
        if ( data != NULL ) {
            for ( int i = 0; i < size && i < number; i++ ) {
                tmp[i] = data[i];
            }
        }
        std::swap( data, tmp );
    }
    size = number;
    if ( tmp != NULL ) {
        delete [] tmp;
    }
}
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
20.07.2014, 10:41     Функция для перевыделения памяти для массива #8
Первое, что бросилось в глаза:
C++
1
2
3
4
5
6
7
//add
//  addElement
template <class T>
void arrayM<T>::addElement( const T &reference ) {
    resize( size + 1 );
    data[size] = reference;
}
Должно быть "data[size - 1] = reference".
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.07.2014, 10:43     Функция для перевыделения памяти для массива #9
Цитата Сообщение от satisfactor Посмотреть сообщение
C++
1
2
3
4
5
6
7
//add
//* addElement
template <class T>
void arrayM<T>::addElement( const T &reference ) {
    resize( size + 1 );
    data[size] = reference;
}
выход за границу массива.
после вызова resize, size будет на единицу больше т.е. size+1.
C++
1
data[size - 1] = reference;

Не по теме:

опоздал

satisfactor
0 / 0 / 0
Регистрация: 11.01.2010
Сообщений: 51
20.07.2014, 12:42  [ТС]     Функция для перевыделения памяти для массива #10
Jupiter,
Убежденный,
спасибо всем, я совсем забыл что решил наращивать размер внутри ressize.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.07.2014, 12:55     Функция для перевыделения памяти для массива
Еще ссылки по теме:

C++ Выделение памяти для непрямоугольного массива
Высвобождение памяти для 3 измерения массива C++
Функция для очистки памяти, выделенную под массив структур C++

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

Или воспользуйтесь поиском по форуму:
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
20.07.2014, 12:55     Функция для перевыделения памяти для массива #11
satisfactor, я бы еще в этом коде поменял кое-какие вещи:

1) Const-версия оператора индексации пусть лучше возвращает "T const &" вместо "T &".
Иначе будет возможна модификация элементов константного объекта. Пример:
C++
1
2
3
4
void modify_item(arrayM<int> const &Arr)
{
    Arr[0] = 123; // Разве это нормально ?
}
2) Инициализацию членов класса в конструкторах вынес в списки инициализации.

3) Все int-ы для индексации и размеров заменил бы на size_t.

И метод show какой-то странный - ничего не возвращает, space не определен...
Yandex
Объявления
20.07.2014, 12:55     Функция для перевыделения памяти для массива
Ответ Создать тему
Опции темы

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