使用 g++ 编译器的 C++ 内存泄漏
C++ Memory Leak using g++ compiler
我正在为我的 C++ class 做一些家庭作业,但是我遇到了这个内存泄漏问题。
我四处寻找,但找不到问题的根源。我还发现奇怪的是,当我在 g++ 中编译它时,内存泄漏在整个程序有 运行.
之后结束,这可能很常见也可能不常见。
如果有人能为我指出正确的方向,那就太棒了。就像我说的,我是初学者。感谢您的帮助。
//--------------- MYSTRING.CPP ---------------
// The class definition for fractions.
//
// Michael Arciola
#include "mystring.h"
#include <typeinfo>
MyString::MyString() // -------------------------------------------------- // #1
{
length = 0;
data = new char[length + 1];
data[0] = '[=10=]';
}
MyString::MyString(const char* s1)
{
length = strlen(s1);
data = new char[length + 1];
for(int i = 0; i < length; i++) {
data[i] = s1[i];
//cout << s1[i];
//cout << data[i];
}
data[length + 1] = '[=10=]';
}
MyString::MyString(int s1)
{
int temp;
char c = 'm';
MyString final;
int count = 0;
length = 0;
data = new char[length + 1];
int s2;
s2 = s1;
while (s1 != 0)
{
temp = s1 % 10;
s1 = s1 / 10;
c = temp + '0';
count++;
}
length = count;
for (int i = length - 1; i >= 0; i--)
{
temp = s2 % 10;
s2 = s2 / 10;
data[i] = temp + '0';
}
data[count] = '[=10=]';
}
// Destructor ----------------------------------------------------------- // #2
MyString::~MyString()
{
delete [] data;
}
// Copy Constructor
MyString::MyString(const MyString& s1)
{
length = s1.length;
data = new char[length + 1];
for (int i = 0; i < length; i++)
{
data[i] = s1.data[i];
}
data[length + 1] = '[=10=]';
}
// Assignment Operator
MyString& MyString::operator=(const MyString& s1)
{
if (this != &s1)
{
delete [] data;
length = s1.length;
data = new char[length + 1];
for (int i = 0; i < length; i++)
{
data[i] = s1.data[i];
}
data[length + 1] = '[=10=]';
}
return *this;
}
ostream& operator<< (ostream& os, const MyString& s1) // --------------- -// #3
{
for (int i = 0; i < s1.length; i++)
{
os << s1.data[i];
}
return os;
}
istream& operator>> (istream& is, MyString& s1)
{
// NEED HELP
/*
is >> s1;
return is;
*/
}
istream& getline (istream& is, MyString& s1, char delim)
{
// NEED HELP
}
bool operator< (const MyString& s1, const MyString& s2) // ------------- // #4
{
if (strcmp(s1.data, s2.data) < 0) {
return true;
} else {
return false;
}
}
bool operator> (const MyString& s1, const MyString& s2)
{
return s2 < s1;
}
bool operator<=(const MyString& s1, const MyString& s2)
{
return !(s2<s1);
}
bool operator>=(const MyString& s1, const MyString& s2)
{
return !(s1<s2);
}
bool operator==(const MyString& s1, const MyString& s2)
{
return (s1<=s2) && (s1>=s2);
}
bool operator!=(const MyString& s1, const MyString& s2)
{
return !(s1==s2);
}
MyString operator+ (const MyString& s1, const MyString& s2) // ------------ // #5
{
MyString newstring;
int len = s1.length + s2.length;
newstring.grow(len);
for (int i = 0; i < s1.length; i++)
{
newstring.data[i] = s1.data[i];
}
for (int i = 0; i < s2.length; i++)
{
newstring.data[s1.length + i] = s2.data[i];
}
return newstring;
}
MyString& MyString::operator+=(const MyString& s1)
{
int start = length;
int growth = s1.length;
int totallen = s1.length + length;
grow(growth, start);
cout << "Start: " << start << endl;
cout << "Length: " << length << endl;
for (int i = start; start < length; i++)
{
cout << "data[i]: " << data[i] << endl;
cout << "s1.data[i]: " << s1.data[i] << endl;
data[i] = s1.data[i];
}
}
char& MyString::operator[] (unsigned int index) // ------------------------ // #6
{
return data[index];
}
const char& MyString::operator[] (unsigned int index) const
{
return data[index];
}
int MyString::getLength() const // ------------------------------------------ // #7
{
return length;
}
const char* MyString::getCString() const
{
return data;
}
MyString MyString::substring(unsigned int start) const // ------------------------- // #8
{
MyString temp;
for (int i = start; i < length; i++)
{
temp.data[i] = data[i];
cout << temp.data[i];
}
return temp;
}
MyString MyString::substring(unsigned int start, unsigned int size) const
{
MyString temp;
if (size + start > length) {
size = length;
} else {
size += start;
}
for (int i = start; i < size; i++)
{
if (i != size)
{
temp.data[i] = data[i];
cout << temp.data[i];
}
}
return temp;
}
MyString& MyString::insert(unsigned int index, const MyString& s) // ---------- // #9
{
if (index > length) {
index = length;
}
grow(s.length, index);
int len = s.length;
int ph = 0;
for (int i = index; i < index + len; i++) {
data[i] = s.data[ph];
ph += 1;
}
}
int MyString::indexOf(const MyString& s) const // ------------------------------// #10
{
int final;
if (strstr(data, s.data) == 0) {
final = -1;
} else {
final = strstr(data, s.data) - data;
}
return final;
}
void MyString::grow(int len) {
char* temp = new char[length + len + 1];
for (int i = 0; i < length; i++)
{
temp[i] = data[i];
}
/* FOR TESTING
for (int i = length; i < length + len; i++)
{
temp[i] = 'm';
}
*/
temp[length + len + 1] = '[=10=]';
data = temp;
length = length + len + 1;
}
void MyString::grow(int len, int index) {
char* temp = new char[length + len + 1];
int ph = 0;
for (int i = 0; i < index; i++)
{
temp[i] = data[i];
ph += 1;
}
for (int i = index; i < index + len; i++)
{
temp[i] = ' ';
}
for (int i = index + len; i < length + len + 1; i++)
{
temp[i] = data[ph];
ph += 1;
}
temp[length + len + 1] = '[=10=]';
data = temp;
length = length + len + 1;
}
void MyString::reverse() {
char temp;
for (int i = 0; i < length/2; i++) { // Loops through array, add value to temp, and move it to the other side of the array
temp = data[i];
data[i] = data[length - i -1];
data[length - i -1] = temp;
cout << data[i] << endl;
}
}
这是我收到的错误。
*** glibc detected *** a.out: double free or corruption (!prev): 0x000000001323d0a0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3b0de714af]
/lib64/libc.so.6(cfree+0x4b)[0x3b0de757ab]
a.out(__gxx_personality_v0+0x38b)[0x400d1b]
a.out[0x402208]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x3b0de1d9f4]
a.out(__gxx_personality_v0+0x49)[0x4009d9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 00:1e 30277703 /home/majors/arciola/COP3330/assignment5/a.out
00603000-00604000 rw-p 00003000 00:1e 30277703 /home/majors/arciola/COP3330/assignment5/a.out
1323d000-1325e000 rw-p 1323d000 00:00 0 [heap]
3b0da00000-3b0da1c000 r-xp 00000000 08:02 10128338 /lib64/ld-2.5.so
3b0dc1c000-3b0dc1d000 r--p 0001c000 08:02 10128338 /lib64/ld-2.5.so
3b0dc1d000-3b0dc1e000 rw-p 0001d000 08:02 10128338 /lib64/ld-2.5.so
3b0de00000-3b0df4f000 r-xp 00000000 08:02 10128359 /lib64/libc-2.5.so
3b0df4f000-3b0e14f000 ---p 0014f000 08:02 10128359 /lib64/libc-2.5.so
3b0e14f000-3b0e153000 r--p 0014f000 08:02 10128359 /lib64/libc-2.5.so
3b0e153000-3b0e154000 rw-p 00153000 08:02 10128359 /lib64/libc-2.5.so
3b0e154000-3b0e159000 rw-p 3b0e154000 00:00 0
3b0e200000-3b0e282000 r-xp 00000000 08:02 10128554 /lib64/libm-2.5.so
3b0e282000-3b0e481000 ---p 00082000 08:02 10128554 /lib64/libm-2.5.so
3b0e481000-3b0e482000 r--p 00081000 08:02 10128554 /lib64/libm-2.5.so
3b0e482000-3b0e483000 rw-p 00082000 08:02 10128554 /lib64/libm-2.5.so
2b79d5f7d000-2b79d5f80000 rw-p 2b79d5f7d000 00:00 0
2b79d5fb1000-2b79d609c000 r-xp 00000000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d609c000-2b79d629c000 ---p 000eb000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d629c000-2b79d62a3000 r--p 000eb000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d62a3000-2b79d62a5000 rw-p 000f2000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d62a5000-2b79d62b8000 rw-p 2b79d62a5000 00:00 0
2b79d62b8000-2b79d62ce000 r-xp 00000000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d62ce000-2b79d64cd000 ---p 00016000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d64cd000-2b79d64ce000 rw-p 00015000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d64ce000-2b79d64d0000 rw-p 2b79d64ce000 00:00 0
7fff51c4e000-7fff51c63000 rw-p 7ffffffe9000 00:00 0 [stack]
7fff51dfd000-7fff51e00000 r-xp 7fff51dfd000 00:00 0 [vdso]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 [vsyscall]
Abort
您的 grow() 方法分配一个新数组,并用该数组替换 data
,而不 delete
[]ing data
的先前内容。那是你的漏洞。
此外,我还看到您的赋值运算符中存在不可移植的未定义行为。比较指向两个对象的指针是未定义的行为,除非对象属于同一个数组或向量。
我正在为我的 C++ class 做一些家庭作业,但是我遇到了这个内存泄漏问题。
我四处寻找,但找不到问题的根源。我还发现奇怪的是,当我在 g++ 中编译它时,内存泄漏在整个程序有 运行.
之后结束,这可能很常见也可能不常见。如果有人能为我指出正确的方向,那就太棒了。就像我说的,我是初学者。感谢您的帮助。
//--------------- MYSTRING.CPP ---------------
// The class definition for fractions.
//
// Michael Arciola
#include "mystring.h"
#include <typeinfo>
MyString::MyString() // -------------------------------------------------- // #1
{
length = 0;
data = new char[length + 1];
data[0] = '[=10=]';
}
MyString::MyString(const char* s1)
{
length = strlen(s1);
data = new char[length + 1];
for(int i = 0; i < length; i++) {
data[i] = s1[i];
//cout << s1[i];
//cout << data[i];
}
data[length + 1] = '[=10=]';
}
MyString::MyString(int s1)
{
int temp;
char c = 'm';
MyString final;
int count = 0;
length = 0;
data = new char[length + 1];
int s2;
s2 = s1;
while (s1 != 0)
{
temp = s1 % 10;
s1 = s1 / 10;
c = temp + '0';
count++;
}
length = count;
for (int i = length - 1; i >= 0; i--)
{
temp = s2 % 10;
s2 = s2 / 10;
data[i] = temp + '0';
}
data[count] = '[=10=]';
}
// Destructor ----------------------------------------------------------- // #2
MyString::~MyString()
{
delete [] data;
}
// Copy Constructor
MyString::MyString(const MyString& s1)
{
length = s1.length;
data = new char[length + 1];
for (int i = 0; i < length; i++)
{
data[i] = s1.data[i];
}
data[length + 1] = '[=10=]';
}
// Assignment Operator
MyString& MyString::operator=(const MyString& s1)
{
if (this != &s1)
{
delete [] data;
length = s1.length;
data = new char[length + 1];
for (int i = 0; i < length; i++)
{
data[i] = s1.data[i];
}
data[length + 1] = '[=10=]';
}
return *this;
}
ostream& operator<< (ostream& os, const MyString& s1) // --------------- -// #3
{
for (int i = 0; i < s1.length; i++)
{
os << s1.data[i];
}
return os;
}
istream& operator>> (istream& is, MyString& s1)
{
// NEED HELP
/*
is >> s1;
return is;
*/
}
istream& getline (istream& is, MyString& s1, char delim)
{
// NEED HELP
}
bool operator< (const MyString& s1, const MyString& s2) // ------------- // #4
{
if (strcmp(s1.data, s2.data) < 0) {
return true;
} else {
return false;
}
}
bool operator> (const MyString& s1, const MyString& s2)
{
return s2 < s1;
}
bool operator<=(const MyString& s1, const MyString& s2)
{
return !(s2<s1);
}
bool operator>=(const MyString& s1, const MyString& s2)
{
return !(s1<s2);
}
bool operator==(const MyString& s1, const MyString& s2)
{
return (s1<=s2) && (s1>=s2);
}
bool operator!=(const MyString& s1, const MyString& s2)
{
return !(s1==s2);
}
MyString operator+ (const MyString& s1, const MyString& s2) // ------------ // #5
{
MyString newstring;
int len = s1.length + s2.length;
newstring.grow(len);
for (int i = 0; i < s1.length; i++)
{
newstring.data[i] = s1.data[i];
}
for (int i = 0; i < s2.length; i++)
{
newstring.data[s1.length + i] = s2.data[i];
}
return newstring;
}
MyString& MyString::operator+=(const MyString& s1)
{
int start = length;
int growth = s1.length;
int totallen = s1.length + length;
grow(growth, start);
cout << "Start: " << start << endl;
cout << "Length: " << length << endl;
for (int i = start; start < length; i++)
{
cout << "data[i]: " << data[i] << endl;
cout << "s1.data[i]: " << s1.data[i] << endl;
data[i] = s1.data[i];
}
}
char& MyString::operator[] (unsigned int index) // ------------------------ // #6
{
return data[index];
}
const char& MyString::operator[] (unsigned int index) const
{
return data[index];
}
int MyString::getLength() const // ------------------------------------------ // #7
{
return length;
}
const char* MyString::getCString() const
{
return data;
}
MyString MyString::substring(unsigned int start) const // ------------------------- // #8
{
MyString temp;
for (int i = start; i < length; i++)
{
temp.data[i] = data[i];
cout << temp.data[i];
}
return temp;
}
MyString MyString::substring(unsigned int start, unsigned int size) const
{
MyString temp;
if (size + start > length) {
size = length;
} else {
size += start;
}
for (int i = start; i < size; i++)
{
if (i != size)
{
temp.data[i] = data[i];
cout << temp.data[i];
}
}
return temp;
}
MyString& MyString::insert(unsigned int index, const MyString& s) // ---------- // #9
{
if (index > length) {
index = length;
}
grow(s.length, index);
int len = s.length;
int ph = 0;
for (int i = index; i < index + len; i++) {
data[i] = s.data[ph];
ph += 1;
}
}
int MyString::indexOf(const MyString& s) const // ------------------------------// #10
{
int final;
if (strstr(data, s.data) == 0) {
final = -1;
} else {
final = strstr(data, s.data) - data;
}
return final;
}
void MyString::grow(int len) {
char* temp = new char[length + len + 1];
for (int i = 0; i < length; i++)
{
temp[i] = data[i];
}
/* FOR TESTING
for (int i = length; i < length + len; i++)
{
temp[i] = 'm';
}
*/
temp[length + len + 1] = '[=10=]';
data = temp;
length = length + len + 1;
}
void MyString::grow(int len, int index) {
char* temp = new char[length + len + 1];
int ph = 0;
for (int i = 0; i < index; i++)
{
temp[i] = data[i];
ph += 1;
}
for (int i = index; i < index + len; i++)
{
temp[i] = ' ';
}
for (int i = index + len; i < length + len + 1; i++)
{
temp[i] = data[ph];
ph += 1;
}
temp[length + len + 1] = '[=10=]';
data = temp;
length = length + len + 1;
}
void MyString::reverse() {
char temp;
for (int i = 0; i < length/2; i++) { // Loops through array, add value to temp, and move it to the other side of the array
temp = data[i];
data[i] = data[length - i -1];
data[length - i -1] = temp;
cout << data[i] << endl;
}
}
这是我收到的错误。
*** glibc detected *** a.out: double free or corruption (!prev): 0x000000001323d0a0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3b0de714af]
/lib64/libc.so.6(cfree+0x4b)[0x3b0de757ab]
a.out(__gxx_personality_v0+0x38b)[0x400d1b]
a.out[0x402208]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x3b0de1d9f4]
a.out(__gxx_personality_v0+0x49)[0x4009d9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 00:1e 30277703 /home/majors/arciola/COP3330/assignment5/a.out
00603000-00604000 rw-p 00003000 00:1e 30277703 /home/majors/arciola/COP3330/assignment5/a.out
1323d000-1325e000 rw-p 1323d000 00:00 0 [heap]
3b0da00000-3b0da1c000 r-xp 00000000 08:02 10128338 /lib64/ld-2.5.so
3b0dc1c000-3b0dc1d000 r--p 0001c000 08:02 10128338 /lib64/ld-2.5.so
3b0dc1d000-3b0dc1e000 rw-p 0001d000 08:02 10128338 /lib64/ld-2.5.so
3b0de00000-3b0df4f000 r-xp 00000000 08:02 10128359 /lib64/libc-2.5.so
3b0df4f000-3b0e14f000 ---p 0014f000 08:02 10128359 /lib64/libc-2.5.so
3b0e14f000-3b0e153000 r--p 0014f000 08:02 10128359 /lib64/libc-2.5.so
3b0e153000-3b0e154000 rw-p 00153000 08:02 10128359 /lib64/libc-2.5.so
3b0e154000-3b0e159000 rw-p 3b0e154000 00:00 0
3b0e200000-3b0e282000 r-xp 00000000 08:02 10128554 /lib64/libm-2.5.so
3b0e282000-3b0e481000 ---p 00082000 08:02 10128554 /lib64/libm-2.5.so
3b0e481000-3b0e482000 r--p 00081000 08:02 10128554 /lib64/libm-2.5.so
3b0e482000-3b0e483000 rw-p 00082000 08:02 10128554 /lib64/libm-2.5.so
2b79d5f7d000-2b79d5f80000 rw-p 2b79d5f7d000 00:00 0
2b79d5fb1000-2b79d609c000 r-xp 00000000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d609c000-2b79d629c000 ---p 000eb000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d629c000-2b79d62a3000 r--p 000eb000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d62a3000-2b79d62a5000 rw-p 000f2000 08:05 3852142 /usr/local/lib64/libstdc++.so.6.0.10
2b79d62a5000-2b79d62b8000 rw-p 2b79d62a5000 00:00 0
2b79d62b8000-2b79d62ce000 r-xp 00000000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d62ce000-2b79d64cd000 ---p 00016000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d64cd000-2b79d64ce000 rw-p 00015000 08:05 3852164 /usr/local/lib64/libgcc_s.so.1
2b79d64ce000-2b79d64d0000 rw-p 2b79d64ce000 00:00 0
7fff51c4e000-7fff51c63000 rw-p 7ffffffe9000 00:00 0 [stack]
7fff51dfd000-7fff51e00000 r-xp 7fff51dfd000 00:00 0 [vdso]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 [vsyscall]
Abort
您的 grow() 方法分配一个新数组,并用该数组替换 data
,而不 delete
[]ing data
的先前内容。那是你的漏洞。
此外,我还看到您的赋值运算符中存在不可移植的未定义行为。比较指向两个对象的指针是未定义的行为,除非对象属于同一个数组或向量。