2015-03-29 3 views
-1

Я работаю над выполнением домашней работы для моего класса C++, но нахожусь в тупике по этой утечке памяти, которую я получаю.C++ Memory Leak с использованием компилятора g ++

Я искал вокруг, но не могу найти источник проблемы. То, что я также нахожу странным, что может быть или не быть обычным, заключается в том, что когда я компилирую его в 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] = '\0'; 
} 

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] = '\0'; 
} 

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] = '\0'; 

} 

// 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] = '\0'; 
} 

// 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] = '\0'; 
    } 

    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] = '\0'; 

    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] = '\0'; 

    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 
+0

Вы спрашиваете **, если ** у вас есть утечка памяти? Или вы знаете, что у вас есть один, но вы не знаете, где? Или вы знаете, где это, но вы не знаете, почему? Или вы знаете, почему, но вы не знаете, как это исправить? Мне непонятно, каков ваш вопрос. –

+0

Я думаю, что в вашем 'const char *' конструкторе 'data [length + 1] = '\ 0';' должно быть 'data [length] = '\ 0';' Также ваш конструктор 'int s' устанавливает' length = 0; 'перед распределением буфера с использованием' length' .... возможно, вам следует выделить после вычисления 'count'? – Galik

+0

где функция 'main'? Вы отправили слишком много кода, а также недостаточно. –

ответ

0

Ваше растет() выделяет новый массив, и заменяет data с массивом, без delete [] ИНГ предыдущего содержимого data. Это твоя утечка.

Кроме того, я также вижу непереносимое, неопределенное поведение в вашем операторе присваивания. Сравнение указателей с двумя объектами - это неопределенное поведение, если только объекты не принадлежат одному и тому же массиву или вектору.

+0

Спасибо вам за ответ! Я считаю, что внес изменения, но по-прежнему получаю эту ошибку после завершения программы. –

+0

Сравнение указателей на разные объекты * не указано * в C++ (все версии). Это UB в C. Более сильные гарантии, чем просто * неуказанные * были добавлены C++ 11, так что 'std :: map ' жизнеспособна. –

+0

«Эта ошибка» - повреждение памяти. Используйте valgrind для кодирования кода и определения нарушения доступа к памяти. Если вы никогда не использовали valgrind раньше, это отличная возможность узнать, как его использовать. –