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

Метод работает как то не понятно - C++

Восстановить пароль Регистрация
 
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
02.03.2014, 20:46     Метод работает как то не понятно #1
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
template <typename TBase>
bool
TArray <TBase>::                            Addition       (TBase          s                )
{
 TBase  *Buffer;
 TBase  *p;
 TBase  *Last;
 size_t  NewSize;
 size_t  NewCount;
 NewCount=Count+1;
 if (NewCount>0)
 {
  NewSize=NewCount*sizeof(TBase);
  if (((NewSize)/sizeof(TBase))==NewCount)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    if (_msize(Buffer)==NewSize)
    {
     Last=Buffer+Count;
     new (Last) TBase;
     *Last=s;
     Count=NewCount;
     Data =Buffer;
     return true;
    }
   }
  }
 }
 return false;
}
Добавлено через 3 минуты
Во-первых при пошаговом исполнении дебагер перскакивает с 23-й строки в вызывющую функцию, потом возвращается обратно.
Во-вторых когда дохожу до деструктора
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <typename TBase>
TArray <TBase>::                           ~TArray         (                                )
{
 TBase  *p;
 size_t  Count;
 if (Data!=NULL)
 {
  for (p=Data+Count-1; p>=Data; --p)
  {
   p->~TBase();
  }
  free(Data);
 }
}
, то дебагер стекоовеловится, если вочить Data, а если не вочить, то на 10-й строке деструктора.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.03.2014, 20:46     Метод работает как то не понятно
Посмотрите здесь:

Код не работает как метод... C++
Как работает метод Пузырька? C++
метод гауса..обьясните как работает программа C++
C++ как работает метод vec.clear()
Не понятно работает C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
02.03.2014, 21:07     Метод работает как то не понятно #2
Да тут вообще какие-то странности у тебя написаны:
C++
1
2
  NewSize=NewCount*sizeof(TBase);
  if (((NewSize)/sizeof(TBase))==NewCount)
В чем смысл этой проверки? Она все время будет true.

А вот эта проверка тоже странная:
C++
1
if (_msize(Buffer)==NewSize)
Ну не может быть памяти меньше, если Buffer != NULL.

А вот это
C++
1
2
new (Last) TBase;
*Last=s;
вообще надо заменить вот этим:
C++
1
new (Last) TBase(s);
Усложняешь, короче.
0x10
02.03.2014, 21:13
  #3

Не по теме:

DrOffset, там еще и явный вызов деструктора... Нафиг.

DrOffset
02.03.2014, 21:18
  #4

Не по теме:

Цитата Сообщение от 0x10 Посмотреть сообщение
DrOffset, там еще и явный вызов деструктора... Нафиг.
Явный там как раз по делу. Ибо у него placement new.

0x10
02.03.2014, 21:23
  #5

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Явный там как раз по делу. Ибо у него placement new.
Да, проглядел.

DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
02.03.2014, 21:30     Метод работает как то не понятно #6
tarasproger, прокрутил сейчас сам алгоритм, вроде все правильно. Ошибка скорее всего не в этом коде.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 05:53  [ТС]     Метод работает как то не понятно #7
А в каком?
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну не может быть памяти меньше, если Buffer != NULL.
Её почему то совсем нет.

Добавлено через 2 минуты
Вызывающая функция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
TArray <std::wstring> &OpenFile(std::wstring  &Path)
{
 TArray <std::wstring> Result;
 std::string           Buffer;
 std::ifstream         File;
 File.open(ToString(Path).c_str());
 while (!File.eof())
 {
  std::getline(File, Buffer);
  Result.Addition(Utf8ToWString(Buffer));
 }
 return Result;
}
Других обращений к объекту result не происходит, глючит именно деструктор Result.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 06:05     Метод работает как то не понятно #8
Хотя бы конструктор TArray покажи
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 06:56  [ТС]     Метод работает как то не понятно #9
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
template <typename TBase>
TArray <TBase>::                            TArray         (                                )
{
 Count=0;
 Data =NULL;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>::                            TArray         (TArray        &Original         )
{
 TBase *Source;
 TBase *Target;
 if (Original.Count>0)
 {
  Data=(TBase*)malloc(_msize(Original.Data));
  if (Data!=NULL)
  {
   Count=_msize(Data)/sizeof(TBase);
   for (Source=Original.Data+Count-1, Target=Data+Count-1; Target>=Data; --Source, --Target)
   {
    new (Target) TBase;
    *Target=*Source;
   }
  }
  else
  {
   Count=0;
  }
 }
}
Добавлено через 31 секунду
Весь класс:
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
template <typename TBase> class TArray
{
//-------------------------------------------------------------------------------------------------
 private:
//-------------------------------------------------------------------------------------------------
  size_t                                    Count;
  TBase                                    *Data;
//-------------------------------------------------------------------------------------------------
 public :
//-------------------------------------------------------------------------------------------------
                                            TArray         (                                );
//-------------------------------------------------------------------------------------------------
                                            TArray         (TArray        &Original         );
//-------------------------------------------------------------------------------------------------
                                           ~TArray         (                                );
//-------------------------------------------------------------------------------------------------
  bool                                      ReSize         (size_t         Count            );
//-------------------------------------------------------------------------------------------------
  bool                                      Empty          (                                );
//-------------------------------------------------------------------------------------------------
  bool                                      Filled         (                                );
//-------------------------------------------------------------------------------------------------
                                            operator size_t(                                );
//-------------------------------------------------------------------------------------------------
  TBase                                    &operator []    (size_t         Index            );
//-------------------------------------------------------------------------------------------------
  TArray                                   &operator =     (TArray        &Original         );
//-------------------------------------------------------------------------------------------------
  bool                                      Addition       (TBase          s                );
//-------------------------------------------------------------------------------------------------
  TBase                                    &Last           (                                );
//-------------------------------------------------------------------------------------------------
};
//=================================================================================================
template <typename TBase>
TArray <TBase>::                            TArray         (                                )
{
 Count=0;
 Data =NULL;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>::                            TArray         (TArray        &Original         )
{
 TBase *Source;
 TBase *Target;
 if (Original.Count>0)
 {
  Data=(TBase*)malloc(_msize(Original.Data));
  if (Data!=NULL)
  {
   Count=_msize(Data)/sizeof(TBase);
   for (Source=Original.Data+Count-1, Target=Data+Count-1; Target>=Data; --Source, --Target)
   {
    new (Target) TBase;
    *Target=*Source;
   }
  }
  else
  {
   Count=0;
  }
 }
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>::                           ~TArray         (                                )
{
 TBase  *p;
 size_t  Count;
 if (Data!=NULL)
 {
  for (p=Data+Count-1; p>=Data; --p)
  {
   p->~TBase();
  }
  free(Data);
 }
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>::                            ReSize         (size_t         Count            )
{
 TBase  *Buffer;
 TBase  *p;
 TBase  *End;
 size_t  NewCount;
 size_t  NewSize;
 NewSize=Count*sizeof(TBase);
 if ((NewSize/sizeof(TBase))==Count)
 {
  if (Count>this->Count)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    NewCount=_msize(Buffer)/sizeof(TBase);
    for (p=Buffer+NewCount-1, End=Buffer+this->Count; p>=End; --p)
    {
     new (p) TBase;
    }
    this->Count=NewCount;
          Data =Buffer;
   }
  }
  if (Count<this->Count)
  {
   if (Count>0)
   {
    for (p=Data+this->Count-1, End=Data+Count; p>=End; --p)
    {
     p->~TBase();
    }
    Buffer=(TBase*)realloc((void*)Data, NewSize);
    NewCount=_msize(Buffer)/sizeof(TBase);
    this->Count=NewCount;
          Data =Buffer;
   }
   else
   {
    for (p=Data+Count-1; p>=Data; --p)
    {
     p->~TBase();
    }
    free(Data);
    this->Count=0;
          Data =NULL;
   }
  }
 }
 return Count==this->Count;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>::                            Empty          (                                )
{
 return (Count==0);
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>::                            Filled         (                                )
{
 return (Count!=0);
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>::                            operator size_t(                                )
{
 return Count;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TBase                                      &
TArray <TBase>::                            operator []    (size_t         Index            )
{
 return *(Data+Index);
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>                             &
TArray <TBase>::                            operator =     (TArray        &Original         )
{
 TBase  *Buffer;
 TBase  *Source;
 TBase  *Target;
 TBase  *p;
 TBase  *End;
 size_t  NewCount;
 size_t  NewSize;
 NewSize=Original.Count*sizeof(TBase);
 if (Original.Count>Count)
 {
  Buffer=(TBase*)realloc((void*)Data, NewSize);
  if (Buffer!=NULL)
  {
   NewCount=_msize(Buffer)/sizeof(TBase);
   for (p=Buffer+NewCount-1, End=Buffer+this->Count; p>=End; --p)
   {
    new (p) TBase;
   }
   for (Target=Buffer+NewCount-1, Source=Original.Data+NewCount-1; Target>=Buffer; --Target, --Source)
   {
    *Target=*Source;
   }
   this->Count=NewCount;
         Data =Buffer;
  }
  else
  {
   if (Data!=NULL)
   {
    for (Target=Buffer+Count-1, Source=Original.Data+Count-1; Target>=Buffer; --Target, --Source)
    {
     *Target=*Source;
    }
   }
  }
  return *this;
 }
 if (Original.Count>0)
 {
  if (Original.Count<Count)
  {
   for (p=Buffer+NewCount-1, End=Buffer+this->Count; p>=End; --p)
   {
    p->~TBase();
   }
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   for (Target=Buffer+Count-1, Source=Original.Data+Count-1; Target>=Buffer; --Target, --Source)
   {
    *Target=*Source;
   }
   this->Count=Count;
         Data =Buffer;
   return *this;
  }
  if (Original.Count==Count)
  {
   for (Target=Data+Count-1, Source=Original.Data+Count-1; Target>=Data; --Target, --Source)
   {
    *Target=*Source;
   }
   return *this;
  }
 }
 if (Original.Count==0)
 {
  if (Data!=NULL)
  {
   for (p=Data+this->Count-1; p>=Data; --p)
   {
    p->~TBase();
   }
   free(Data);
   this->Count=0;
         Data =NULL;
  }
  return *this;
 }
 return *this;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>::                            Addition       (TBase          s                )
{
 TBase  *Buffer;
 TBase  *p;
 size_t  NewSize;
 size_t  NewCount;
 NewCount=Count+1;
 if (NewCount>0)
 {
  NewSize=NewCount*sizeof(TBase);
  if (((NewSize)/sizeof(TBase))==NewCount)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    if (_msize(Buffer)==NewSize)
    {
     new (Buffer+Count) TBase(s);
     Count=NewCount;
     Data =Buffer;
     return true;
    }
   }
  }
 }
 return false;
}
//-------------------------------------------------------------------------------------------------
template <typename TBase>
TBase                                      &
TArray <TBase>::                            Last           (                                )
{
 return *(Data+Count-1);
}
Добавлено через 1 минуту
Не деструктится конкретный объект, я его знаю: сравнил this в конструкторах и в глючном деструкторе.

Добавлено через 18 минут
Перескок больше не происходит, но глюк в деструкторе тот же.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 16:01     Метод работает как то не понятно #10
Ошибок на самом деле море.
Метод addition должен принимать константную ссылку (зачем лишнее копирование аргумента?), проверки, про которые я уже говорил - не нужны. Не знаю зачем ты их оставил, но они ровным счетом ничего не дают.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <typename TBase>
bool TArray <TBase>::Addition(TBase const &s)
{
    TBase  *Buffer;
    size_t  NewSize;
    size_t  NewCount;
    NewCount = Count + 1;
    if (NewCount > 0)
    {
        NewSize = NewCount * sizeof(TBase);
        Buffer  = (TBase*)realloc(Data, NewSize);
        if(Buffer!=NULL)
        {
            new (Buffer+Count) TBase(s);
            Count=NewCount;
            Data =Buffer;
            return true;
        }
    }
    return false;
}
В нормальных реализациях для operator[] нужно предусматривать и его константную версию:
C++
1
2
3
4
5
template <typename TBase>
TBase const & TArray <TBase>::operator[](size_t  Index ) const
{
    return *(Data+Index);
}
Конструктор копирования реализован неверно (вызывает присваивание вместо копирования у хранимых объектов!), кроме того он должен принимать константную ссылку. msize опять же нафиг не нужен, зачем, если есть Original.Сount? Предварительная инициализация полей нужна.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename TBase>
TArray <TBase>::TArray(TArray const & Original)
    : Count(0), Data(NULL)
{
    if(Original.Count > 0)
    {
        Data = (TBase*)malloc(Original.Count);
        if(Data != NULL)
        {
            Count = Original.Count;
            for(size_t i = 0; i < Count; ++i)
            {
                new(Data + i) TBase(Original[i]);
            }
        }
    }
}
В деструкторе затесалась неизвестная переменная Count, которая перекрыла Count из класса. Собственно поэтому и падало:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename TBase>
TArray <TBase>::~TArray()
{
    TBase  *p;
    if (Data!=NULL)
    {
        for(p=Data+Count-1; p>=Data; --p)
        {
            p->~TBase();
        }
        free(Data);
    }
}
функция OpenFile почему-то возвращает ссылку на временный объект! Этого делать ни в коем случае нельзя!
В остальном коде все примерно так же.
_msize выкинуть вообще, т.к. не нужен.
Для удаления предусмотреть функцию deallocate, чтобы не повторяться.
Проконтролировать где объект изменяется, а где нет, соответственно расставив правильно const.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 16:09  [ТС]     Метод работает как то не понятно #11
Цитата Сообщение от DrOffset Посмотреть сообщение
функция OpenFile почему-то возвращает ссылку на временный объект!
Это просто временная закорючка в надежде сократить количество вызовов конструкторов и деструкторов, функция же возвращает значение локального объекта.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 16:11     Метод работает как то не понятно #12
Цитата Сообщение от taras atavin Посмотреть сообщение
Это просто временная закорючка в надежде сократить количество вызовов конструкторов
это UB. Объект в функции уже уничтожился, а ссылка на него есть. Ссылка в таком состоянии - undefined behaviour.
Об этом должен был верещать компилятор warning`ами.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 16:12  [ТС]     Метод работает как то не понятно #13
Функция возвращает значение.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 16:15     Метод работает как то не понятно #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Функция возвращает значение.
Значение - это вот так:
C++
1
TArray <std::wstring> func();
А если вот так:
C++
1
TArray <std::wstring> & func();
То это ссылка на значение локального объекта функции. Который уничтожился после выхода из области видимости функции. И ссылка стала невалидной.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 16:27  [ТС]     Метод работает как то не понятно #15
Цитата Сообщение от DrOffset Посмотреть сообщение
Значение - это вот так:
Код C++
1
TArray <std::wstring> func();
А если вот так:
Код C++
1
TArray <std::wstring> & func();
Прям я не знаю. Читай:
Цитата Сообщение от taras atavin Посмотреть сообщение
Это просто временная закорючка в надежде сократить количество вызовов конструкторов и деструкторов,
.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 16:36     Метод работает как то не понятно #16
taras atavin, да все я понял. Я тебе объяснил почему так делать нельзя. А то, что ты это уберешь потом - понятно.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
03.03.2014, 16:36  [ТС]     Метод работает как то не понятно #17
1. Убрал, а не уберу. Сразу, как только деструктор заработал.
2. Почему так нельзя я сам могу объяснить.
3. При дебаге деструктора какое мне дело до того, что функция, получающая ссылку, не достучится до данных? До этой гоги я просто не дойду.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.03.2014, 16:43     Метод работает как то не понятно
Еще ссылки по теме:

как i двигается понятно но вот не понятно как это делает j ? C++
Не совсем понятно как работает такой код C++
Не понятно почему не работает компилятор DevC++ C++

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

Или воспользуйтесь поиском по форуму:
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,585
03.03.2014, 16:43     Метод работает как то не понятно #18
Ладно, фиг с ним с деструктором, я потом увидел, что ты еще одну тему создал и нашел там ошибку сам. Остальное-то понятно?
Yandex
Объявления
03.03.2014, 16:43     Метод работает как то не понятно
Ответ Создать тему
Опции темы

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