Debug Error!
Program: f:\Roman\Roman\testvecmat.exe
Invalid allocation size: 4294967295 bytes
(Press Retry to debug the application).
В отладчике в функции operator+(const myNVector& vect1, const myNVector& vect2) всё нормально, а потом происходит обращение к функции operator=(const myNVector &vect) и там с самого начала у переменной vect поле n равно -858993460 , а поле massif вообще не читается.
В чём причина этого? Как исправить ошибку, чтобы Ares = Avect + Avect2; нормально работало?
1613 г. = 2024 г.
Re: Проблема с перегрузкой бинарного оператора + в классе
Вы возвращаете адрес временного объекта, оператор + в каноническом виде всегда возращает копию. Если вы напишите myNVector operator+(const myNVector& vect1, const myNVector& vect2), все будет ОК.
Это что касается вашего вопроса, а по остальному пересмотрите дизайн в пользу: std::vector<double>
Re[2]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, saf_e, Вы писали:
_>Вы возвращаете адрес временного объекта, оператор + в каноническом виде всегда возращает копию. Если вы напишите myNVector operator+(const myNVector& vect1, const myNVector& vect2), все будет ОК.
Сделал так. В результате у меня появляется другая ошибка:
Debug Assertion Failed!
Program f:\Roman\Roman\testvecmat\Debug\testvecmat.exe
File f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUSE)
Вот текст файла dbgdel.cpp:
/***
*dbgdel.cpp - defines C++ scalar delete routine, debug version
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* Defines C++ scalar delete() routine.
*
*******************************************************************************/#ifdef _DEBUG
#include <cruntime.h>
#include <malloc.h>
#include <mtdll.h>
#include <dbgint.h>
#include <rtcsup.h>
/***
*void operator delete() - delete a block in the debug heap
*
*Purpose:
* Deletes any type of block.
*
*Entry:
* void *pUserData - pointer to a (user portion) of memory block in the
* debug heap
*
*Return:
* <void>
*
*******************************************************************************/void operator delete(
void *pUserData
)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
#endif/* _DEBUG */
52-ая строка в нём -- это _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
Что это означает? Как я понимаю, это связано с настройками с управлением памятью.
Как это исправить?
1613 г. = 2024 г.
Re[3]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, RussianFellow, Вы писали:
RF>Здравствуйте, saf_e, Вы писали:
_>>Вы возвращаете адрес временного объекта, оператор + в каноническом виде всегда возращает копию. Если вы напишите myNVector operator+(const myNVector& vect1, const myNVector& vect2), все будет ОК.
RF>Сделал так. В результате у меня появляется другая ошибка:
RF>Что это означает? Как я понимаю, это связано с настройками с управлением памятью. RF>Как это исправить?
Это значит что где-то порушилась память. На первый взгляд, код правильный.
Вы нашли одну из причин, почему в с++ пропагандируют не пользоваться неуправляемой памятью Ошибки не всегда очевидны и их легко допустить.
Используйте std::vector<long double> и наступит вам счастье.
Re[4]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, RussianFellow, Вы писали:
RF>Здравствуйте, saf_e, Вы писали:
_>>Используйте std::vector<long double> и наступит вам счастье.
RF>Про std::vector я знаю.
RF>Но я бы хотел всё-таки разобраться с моим классом myNVector.
Факап был неочевиден, но предсказуем
При выходе из ф-ции временный объект будет передан наружу ч-з копирование (RVO штука опциональная), т.к. конструктора копирования у вас нет, происходит поверхностное копирование, и память расстреливается.
Если бы вы хранили буффер в std::unique_ptr, компилятор вам бы об этом намекнул.
Re[6]: Проблема с перегрузкой бинарного оператора + в классе
Я решил проблему -- создал глобальные переменные pGlobal типа long double* и nGlobal типа int.
В функции operator+ я выделяю память для pGlobal с помощью new [] (количество элементов этого массива совпадает с размерностью вектора), nGlobal я присваиваю значение размерности вектора и с помощью функции memmove я помещаю в pGlobal элемента поля massif моего класса myNVector.
А в функции operator= я с помощью той же функции memmove я считываю данные из pGlobal в поле massif моего объекта, а полю n моего объекта я присваиваю значение nGlobal.
1613 г. = 2024 г.
Re[7]: Проблема с перегрузкой бинарного оператора + в классе
09.11.2013 11:17, RussianFellow пишет:
> Я решил проблему -- создал глобальные переменные pGlobal типа long > double* и nGlobal типа int. > В функции operator+ я выделяю память для pGlobal с помощью new [] > (количество элементов этого массива совпадает с размерностью вектора), > nGlobal я присваиваю значение размерности вектора и с помощью функции > memmove я помещаю в pGlobal элемента поля massif моего класса myNVector. > А в функции operator= я с помощью той же функции memmove я считываю > данные из pGlobal в поле massif моего объекта, а полю n моего объекта я > присваиваю значение nGlobal.
Бррр. Может ты лучше на С#, Java программировать будешь. Потом же
кому-то твое будет падать и он будет долго разгребаться — пожалей коллег.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, Vzhyk, Вы писали:
V>Бррр. Может ты лучше на С#, Java программировать будешь. Потом же V>кому-то твое будет падать и он будет долго разгребаться — пожалей коллег.
Я посидел в отладчике, проверил все варианты--всё нормально у меня работает. Надо только знать, где следует подчищать память из pGlobal и nGlobal.
1613 г. = 2024 г.
Re[9]: Проблема с перегрузкой бинарного оператора + в классе
09.11.2013 13:19, RussianFellow пишет:
> всё нормально у меня работает
Вот за эту фразу программистов надо сразу выгонять в дворники. Это было
из идеального мира.
В реальном есть много контор, где такое приветствуется — правда они все
попильные.
Posted via RSDN NNTP Server 2.1 beta
Re[9]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, RussianFellow, Вы писали:
RF>Я решил проблему -- создал глобальные переменные pGlobal типа long double* и nGlobal типа int.
Не решил, а перепрятал.
RF>В функции operator+ я выделяю память для pGlobal с помощью new [] (количество элементов этого массива совпадает с размерностью вектора), nGlobal я присваиваю значение размерности вектора и с помощью функции memmove я помещаю в pGlobal элемента поля massif моего класса myNVector. RF>А в функции operator= я с помощью той же функции memmove я считываю данные из pGlobal в поле massif моего объекта, а полю n моего объекта я присваиваю значение nGlobal.
Если уж изобретать велосипед, то делать это хотя бы канонически, а не тревожными воспоминаниями о лихих 80-х и K&R C.
class MyVec
{
public:
typedef long double element_type;
private: // потому что нечего кому ни попадя лазить в недра
element_type* data_;
size_t dim_;
public:
// доступ
size_t dim() const { return dim_; }
element_type* data() const { return data_; } // читать-писать, но не создавать-удалять!
element_type & operator[](size_t i) { assert(i<dim_); return data_[i]; }
element_type const& operator[](size_t i) const { assert(i<dim_); return data_[i]; }
// конструкторы-монструкторыexplicit// чтобы не было соблазна приводить скаляр к вектору
MyVec(size_t d = 0) : dim_(d), data_(d ? new element_type[d] : nullptr) {}
~MyVec() { delete[] data_; }
MyVec(const MyVec& v) : dim_(v.dim_), data_(new element_type[v.dim_]) { std::copy(data_, data_+dim_, v.data_); } // вместо memmove
MyVec(MyVec&& v) : dim_(v.dim_), data_(v.data_) { v.dim_ = 0; v.data_ = nullptr; } // C++11: перемещающий конструктор
MyVec& operator=(const MyVec& v) { if(&v != this) MyVec(v).swap(*this); return *this; }
MyVec& operator=(MyVec&& v) { v .swap(*this); return *this; } // C++11: перемещающее присваиваниеvoid swap(MyVec& v) { std::swap(dim_, v.dim_); std::swap(data_, v.data_); }
// операторы-моператоры
MyVec operator + (MyVec const& v) const
{
assert(dim() == v.dim());
MyVec result(dim()); // всё, на этом управление памятью закончили
std::transform(data(), data()+dim(), v.data(), result.data(), std::plus<long double>());
return result;
}
};
Перекуём баги на фичи!
Re[9]: Проблема с перегрузкой бинарного оператора + в классе
Здравствуйте, RussianFellow, Вы писали:
RF>Здравствуйте, Vzhyk, Вы писали:
V>>Бррр. Может ты лучше на С#, Java программировать будешь. Потом же V>>кому-то твое будет падать и он будет долго разгребаться — пожалей коллег.
RF>Я посидел в отладчике, проверил все варианты--всё нормально у меня работает. Надо только знать, где следует подчищать память из pGlobal и nGlobal.
Маленький совет, или учитесь как делать правильно (вам уже "over 9000" вариантов предложили). Или идите из С++ туда где ваши методы пригодяться, например сайты на РНР писать... Они все равно одноразовые, потом проще переделать.