我在使用g ++的析构函数时遇到一些问题,在MinGW上工作得很好...... 看起来问题是当我随意摧毁物体时,试图让程序摧毁它们......
我编译这段代码
#include <iostream>
#include <string.h>
using namespace std;
class Alumno{
public:
Alumno(string, int);
~Alumno();
void Print();
private:
string name;
int age;
};
Alumno::Alumno(string n="------", int e=0)
{
name = n;
age = e;
}
Alumno::~Alumno()
{
cout << "Done" << endl;
}
void Alumno::Print()
{
cout << "Name: " << name << endl;
cout << "Age: " << age << endl;
}
int main()
{
Alumno a;
a.Print();
cout << endl;
a.~Alumno();
cout << endl;
Alumno a2("john",20);
Alumno *ptrA=&a2;
a2.Print();
cout << endl;
a2.~Alumno();
ptrA->~Alumno();
Alumno a3("Ana");
a3.Print();
return 0;
}
我得到了回复,我不知道这是什么......
Name: ------
Age: 0
Done
Name: john
Age: 20
Done
Done
*** Error in `./a.out': double free or corruption (fasttop): 0x00000000022e8010 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3ebde7d0b8]
/lib64/libstdc++.so.6(_ZNSsD1Ev+0x1f)[0x3ec82ba00f]
./a.out[0x400cd5]
./a.out[0x400e80]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x3ebde21b45]
./a.out[0x400b79]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:02 1581527 /home/ekiim/Documents/POO/a.out
00601000-00602000 r--p 00001000 fd:02 1581527 /home/ekiim/Documents/POO/a.out
00602000-00603000 rw-p 00002000 fd:02 1581527 /home/ekiim/Documents/POO/a.out
022e8000-02309000 rw-p 00000000 00:00 0 [heap]
3ebda00000-3ebda21000 r-xp 00000000 fd:00 1835646 /usr/lib64/ld-2.17.so
3ebdc20000-3ebdc21000 r--p 00020000 fd:00 1835646 /usr/lib64/ld-2.17.so
3ebdc21000-3ebdc22000 rw-p 00021000 fd:00 1835646 /usr/lib64/ld-2.17.so
3ebdc22000-3ebdc23000 rw-p 00000000 00:00 0
3ebde00000-3ebdfb6000 r-xp 00000000 fd:00 1835999 /usr/lib64/libc-2.17.so
3ebdfb6000-3ebe1b6000 ---p 001b6000 fd:00 1835999 /usr/lib64/libc-2.17.so
3ebe1b6000-3ebe1ba000 r--p 001b6000 fd:00 1835999 /usr/lib64/libc-2.17.so
3ebe1ba000-3ebe1bc000 rw-p 001ba000 fd:00 1835999 /usr/lib64/libc-2.17.so
3ebe1bc000-3ebe1c1000 rw-p 00000000 00:00 0
3ebee00000-3ebef01000 r-xp 00000000 fd:00 1839117 /usr/lib64/libm-2.17.so
3ebef01000-3ebf100000 ---p 00101000 fd:00 1839117 /usr/lib64/libm-2.17.so
3ebf100000-3ebf101000 r--p 00100000 fd:00 1839117 /usr/lib64/libm-2.17.so
3ebf101000-3ebf102000 rw-p 00101000 fd:00 1839117 /usr/lib64/libm-2.17.so
3ebfe00000-3ebfe15000 r-xp 00000000 fd:00 1843105 /usr/lib64/libgcc_s-4.8.2-20131212.so.1
3ebfe15000-3ec0014000 ---p 00015000 fd:00 1843105 /usr/lib64/libgcc_s-4.8.2-20131212.so.1
3ec0014000-3ec0015000 r--p 00014000 fd:00 1843105 /usr/lib64/libgcc_s-4.8.2-20131212.so.1
3ec0015000-3ec0016000 rw-p 00015000 fd:00 1843105 /usr/lib64/libgcc_s-4.8.2-20131212.so.1
3ec8200000-3ec82e6000 r-xp 00000000 fd:00 1839064 /usr/lib64/libstdc++.so.6.0.19
3ec82e6000-3ec84e5000 ---p 000e6000 fd:00 1839064 /usr/lib64/libstdc++.so.6.0.19
3ec84e5000-3ec84ed000 r--p 000e5000 fd:00 1839064 /usr/lib64/libstdc++.so.6.0.19
3ec84ed000-3ec84ef000 rw-p 000ed000 fd:00 1839064 /usr/lib64/libstdc++.so.6.0.19
3ec84ef000-3ec8504000 rw-p 00000000 00:00 0
7ff36bfa5000-7ff36bfa6000 rw-p 00000000 00:00 0
7ff36bfa6000-7ff36bfa8000 rw-p 00000000 00:00 0
7ff36bfa8000-7ff36bfa9000 rw-p 00000000 00:00 0
7ff36bfa9000-7ff36bfaa000 rw-p 00000000 00:00 0
7ff36bfcc000-7ff36bfcd000 rw-p 00000000 00:00 0
7ff36bfcd000-7ff36bfce000 rw-p 00000000 00:00 0
7ff36bfce000-7ff36bfcf000 rw-p 00000000 00:00 0
7fff4d4e7000-7fff4d508000 rw-p 00000000 00:00 0 [stack]
7fff4d5fe000-7fff4d600000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
任何帮助?
答案 0 :(得分:1)
你不应该直接调用析构函数(仅限于一些罕见的特殊场合)。当函数返回并且在堆栈上分配对象(您正在做什么)或在堆上调用delete
时,它会自动调用。
答案 1 :(得分:0)
发生了什么~Alumno()正在调用std :: string的析构函数。虽然Alumno没有进行任何自定义内存管理,但是std :: string会这样做,所以第二次导致双重释放〜调用Alumno()。
尝试运行此代码。它与您的代码中发生的情况类似,其中A类是alumno的替代品,B类是std :: string的替代品。
#include <iostream>
class B
{
public:
~B() { std::cout << "~B()" << std::endl; }
};
class A
{
public:
~A() { std::cout << "~A()" << std::endl; }
B myB;
};
void foo (void)
{
A myA;
myA.~A();
}
int main(int argc, char * argv[])
{
foo();
system("pause");
return 0;
}
它应该产生这个输出......
~A()
~B()
~A()
~B()
总的来说,这有两个很大的好处......
1)不要手动调用析构函数(这有一个例外,当使用 placement new 这是非常模糊的时候。)
2)Linux上有一个名为 valgrind 的酷工具。我不知道你是否可以访问它,但如果你这样做,那么当你有奇怪的内存问题时就使用它。它往往是有启发性的。