C++ 内存泄漏 (valgrind)
C++ memory leak (valgrind)
Valgrind 声称我正在间接失去记忆;让我烦恼的是,我不知道为什么会这样。
不确定这是误报还是我只是不理解某些指针赋值之类的东西。
我是不是失忆了?如果是,为什么?
Valgrind 报告:
==24392== 21 bytes in 2 blocks are indirectly lost in loss record 1 of 3
==24392== at 0x4028699: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24392== by 0x804B41D: Perishable::load(std::basic_fstream<char, std::char_traits<char> >&) (Perishable.cpp:42)
==24392== by 0x804C504: sict::PosApp::loadRecs() (PosApp.cpp:139)
==24392== by 0x804D58E: sict::PosApp::run() (PosApp.cpp:393)
==24392== by 0x8049337: main (milestone4.cpp:8)
这是第 42 行:
std::fstream& Perishable::load(std::fstream& stream) {
char mysku[MAX_SKU_LEN + 1];
char mynam[100];
bool mytax;
double myprice;
int myqty;
int date[5];
stream.getline(mysku, 100, ',');
sku(mysku);
stream.getline(mynam, 100, ',');
name(mynam);//bytes indirectly lost
这是 name() [完全评论]
void Item::name(char *name){
delete[] _name; //..............Just in case it points to something.
//..............Note: How could I possibly be losing memory with this line here??
int x = strlen(name); //........Grab the length of the new input
if (_name == '[=12=]') {//..........If it was empty, ie. its the first assignment
_name = new char[x + 1];//..Allocate the space, +1 for null char
}
for (int i = 0; i < x; i++) {//.Copy
_name[i] = name[i];
}
_name[x] = '[=12=]';//............Yeah, its manual termination. I should maybe use strcpy
}
编辑>>>这里是析构函数
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
_name = '[=13=]';
}
编辑>>复制构造函数和赋值运算符
//Copy Constructor
Item::Item(const Item& copyfrom){
(*this) = copyfrom;
}
//Member operators
Item& Item::operator=(const Item &myitem) {
if (!myitem.isEmpty()){
init((*this), myitem._sku, myitem._name, myitem._price, myitem._taxed);
this->_quantity = myitem._quantity;
}
return (*this);
}
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
int length = strlen(name);
int skulength = strlen(sku);
obj._price = priced;
obj._taxed = taxed;
obj._quantity = 0;
obj._name = new char[length+1]; //+1 for the null which wasn't counted. Huge pain debugging that.
for (int i = 0; i < length; i++) {
obj._name[i] = name[i];
if (i < skulength) {//redundanc
obj._sku[i] = sku[i];
}
}
obj._name[length] = '[=14=]';
obj._sku[skulength] = '[=14=]';
}
如果你真的必须使用 new
和裸指针(提示:几乎没有人这样做),那么你需要确保 _name
的所有者在不再需要它时释放它。
正确的位置可能 ~Item()
析构函数,但如果没有其余代码,很难确定。
我只看到:
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
// Don't reassign
}
和
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
// ...
if (obj._name == nullptr /* 0 */) {
obj._name = new char[length+1];
// What if it's not null?
} else {
// Do you want to delete and new up a char?
}
}
此外,使用非常量引用对我来说很可怕。我看到 init 中 obj._name 的 new-ing 是最大的问题,没有任何先发制人的检查。
Valgrind 声称我正在间接失去记忆;让我烦恼的是,我不知道为什么会这样。
不确定这是误报还是我只是不理解某些指针赋值之类的东西。
我是不是失忆了?如果是,为什么?
Valgrind 报告:
==24392== 21 bytes in 2 blocks are indirectly lost in loss record 1 of 3
==24392== at 0x4028699: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24392== by 0x804B41D: Perishable::load(std::basic_fstream<char, std::char_traits<char> >&) (Perishable.cpp:42)
==24392== by 0x804C504: sict::PosApp::loadRecs() (PosApp.cpp:139)
==24392== by 0x804D58E: sict::PosApp::run() (PosApp.cpp:393)
==24392== by 0x8049337: main (milestone4.cpp:8)
这是第 42 行:
std::fstream& Perishable::load(std::fstream& stream) {
char mysku[MAX_SKU_LEN + 1];
char mynam[100];
bool mytax;
double myprice;
int myqty;
int date[5];
stream.getline(mysku, 100, ',');
sku(mysku);
stream.getline(mynam, 100, ',');
name(mynam);//bytes indirectly lost
这是 name() [完全评论]
void Item::name(char *name){
delete[] _name; //..............Just in case it points to something.
//..............Note: How could I possibly be losing memory with this line here??
int x = strlen(name); //........Grab the length of the new input
if (_name == '[=12=]') {//..........If it was empty, ie. its the first assignment
_name = new char[x + 1];//..Allocate the space, +1 for null char
}
for (int i = 0; i < x; i++) {//.Copy
_name[i] = name[i];
}
_name[x] = '[=12=]';//............Yeah, its manual termination. I should maybe use strcpy
}
编辑>>>这里是析构函数
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
_name = '[=13=]';
}
编辑>>复制构造函数和赋值运算符
//Copy Constructor
Item::Item(const Item& copyfrom){
(*this) = copyfrom;
}
//Member operators
Item& Item::operator=(const Item &myitem) {
if (!myitem.isEmpty()){
init((*this), myitem._sku, myitem._name, myitem._price, myitem._taxed);
this->_quantity = myitem._quantity;
}
return (*this);
}
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
int length = strlen(name);
int skulength = strlen(sku);
obj._price = priced;
obj._taxed = taxed;
obj._quantity = 0;
obj._name = new char[length+1]; //+1 for the null which wasn't counted. Huge pain debugging that.
for (int i = 0; i < length; i++) {
obj._name[i] = name[i];
if (i < skulength) {//redundanc
obj._sku[i] = sku[i];
}
}
obj._name[length] = '[=14=]';
obj._sku[skulength] = '[=14=]';
}
如果你真的必须使用 new
和裸指针(提示:几乎没有人这样做),那么你需要确保 _name
的所有者在不再需要它时释放它。
正确的位置可能 ~Item()
析构函数,但如果没有其余代码,很难确定。
我只看到:
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
// Don't reassign
}
和
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
// ...
if (obj._name == nullptr /* 0 */) {
obj._name = new char[length+1];
// What if it's not null?
} else {
// Do you want to delete and new up a char?
}
}
此外,使用非常量引用对我来说很可怕。我看到 init 中 obj._name 的 new-ing 是最大的问题,没有任何先发制人的检查。