Утечка памяти в функции с++

229
15 августа 2017, 15:35

Есть такое задание :

Реализуйте функцию getline, которая считывает поток ввода посимвольно, пока не достигнет конца потока или не встретит символ переноса строки ('\n'), и возвращает C-style строку с прочитанными символами.

Обратите внимание, что так как размер ввода заранее неизвестен, то вам нужно будет перевыделять память в процессе чтения, если в потоке ввода оказалось больше символов, чем вы ожидали.

Память, возвращенная из функции будет освобождена оператором delete[]. Символ переноса строки ('\n') добавлять в строку не нужно, но не забудьте, что в конце C-style строки должен быть завершающий нулевой символ.

Требования к реализации: при выполнении данного задания вы можете определять любые вспомогательные функции, если они вам нужны. Определять функцию main не нужно.

Я написал такую функцию:

int g = 0;
int i = 0;
char c;
int k = 1;
char * m = new char[k];
char * str = 0;
while (((c = std::cin.get()) != '\n') && (!std::cin.eof())) {
    g = 0;
    i = 0;
    str = new char[k];
    while ((m[i]) && (m[i] != '\0')) {
        str[i] = m[i];
        i += 1;
    }
    delete [] m;
    m = 0;
    str[i] = c;
    m = new char[k];
    while (str[g]) {
        m[g] = str[g];
        g++;
    }
    delete [] str;
    str = 0;
    k += 1;
}   
m[i+1] = '\0';
return m;   

При небольшом количестве символов все работает хорошо. Но когда символов больше 20, то код крашится. Я догадываюсь, что проблема в утечке памяти, но найти ошибку не могу. Как исправить функцию?

Answer 1

Признаться честно, сложно понять, что у вас происходит в коде. Но падает программа из-за попытки чтения за пределами строки.

while ((m[i]) && (m[i] != '\0')) ...

Это условие цикла какое-то очень странное. Вы хотите найти ноль, который вы туда не записываете (точнее пытаетесь записать, но после этого цикла).

Думаю, стоит ознакомиться, с моим адаптированным примерчиком. Копирование тут реализовано вызовом библиотечной функции std::copy.

char* get_full_line(std::istream& f = std::cin)
{
    size_t capacity = 16;  // начальный объем массива
    char* str = new char[capacity];
    size_t length = 0;
    int ch;
    while ((ch = f.get()) != '\n' && !f.eof()) {
        if (length >= capacity) {
            // место в строке закончилось, перевыделение памяти
            char* p = new char[capacity *= 4];  // коэфициент прироста
            std::copy(str, str + length, p);
            delete[] str;
            str = p;
        }
        str[length++] = ch;
    }
    str[length] = '\0';
    return str;
}
READ ALSO
Проблема с создание вектора в классе, С++

Проблема с создание вектора в классе, С++

Я создаю вектор ссылок на объекты моего класса в главной функции - всё работает замечательноСоздаю схожий вектор в ином классе - всё работать...

199
Считывание экрана окна с помощью opencv и С++ [требует правки]

Считывание экрана окна с помощью opencv и С++ [требует правки]

Как это правильно реализовать, чтобы захват был в Mat?

235
Сканер портов не может подключиться к хосту

Сканер портов не может подключиться к хосту

Написал простой сканер портов на асинхронных сокетахСоединение при сканировании mail

205
Visual studio не работает exe [дубликат]

Visual studio не работает exe [дубликат]

На данный вопрос уже ответили:

229