Бесконечный спам пробелов при выводе всех элементов односвязного списка c++
При вызове функции void printToConsole() после добавления минимум одного элемента в список происходит бесконечный спам пробелов в консоль, это как-то связано с утечкой памяти или какая проблема в данной ситуации? Такая же ситуация была с функцией void printInFile(), но исправив Node *p = first; на Node *p = last; ситуация пофиксилась. Чего не происходит с void printToConsole().
#include <stdint.h>
#include <fstream>
#include "namespace_consts.h"
using namespace std;
struct Node
{
string *persons;
Node *next;
Node(string *_persons) : persons(_persons), next(nullptr) {}
~Node()
{
delete[] persons;
}
};
struct list
{
Node *first;
Node *last;
list() : first(nullptr), last(nullptr) {}
~list()
{
Node *p = first;
while (p)
{
Node *next = p->next;
delete p;
p = next;
}
}
bool is_empty()
{
return first == nullptr;
}
void push_back(string *_val)
{
Node *p = new Node(_val);
if (is_empty())
{
first = p;
last = p;
return;
}
last->next = p;
last = p;
}
void printToConsole()
{
if (is_empty())
return;
Node *p = first;
while (p)
{
for (uint8_t i = 0; i < 5; i++)
cerr << p->persons[i];
cerr << endl;
p = p->next;
}
}
void printInFile()
{
if (is_empty())
return;
Node *p = last;
ofstream myFile(constText::defaultPath, ios::app);
while (p)
{
if (myFile.is_open())
{
for (uint8_t i = 0; i < 5; i++)
myFile << p->persons[i];
myFile << endl;
p = p->next;
}
}
myFile.close();
}
};
UPD: Сейчас добавил функцию считывания списка с файла. Если после считывания с файла вывести инфу в консоль, все корректно отображается, получается проблема в функции void push_back(). но вот что именно не так с ней не пойму..
void readFromFile()
{
ifstream myReadFile(constText::defaultPath);
string myText;
while (getline(myReadFile, myText))
{
string *data = new string[5];
uint8_t j = 0;
for (uint8_t i = 0; i < myText.length(); i++)
{
if (myText[i] == ';')
j++;
j < 4 ? data[j] += myText[i] : data[4] += myText[i];
}
pushBack(data);
}
myReadFile.close();
}
Ответы (1 шт):
Проверил работу вашего кода таким образом
int main()
{
string* a = new string[5] {"A", "B", "C", "D", "E"};
string* b = new string[5] {"A", "B", "C", "D", "E"};
list l;
l.push_back(a);
l.push_back(b);
l.printToConsole(); // Output: ABCDE\nABCDE
return 0;
}
В таком варианте все работает, вывод корректен, соответственно метод push_back отрабатывает нормально, для того, чтобы понять в чем ваша проблема приведите вариант использования вашей структуры при которой работа неправильная.
Так же есть некоторые вопросы к вашей реализации:
void printToConsole()
{
...
while (p)
{
for (uint8_t i = 0; i < 5; i++)
cerr << p->persons[i];
...
}
...
}
Почему вы распечатываете ровно 5 элементов? Если их окажется меньше 5, то вы столкнетесь с Undefined Behavior, связанным с доступом к памяти, которой вы не владеете (выход за границы массива), если их будет больше, чем 5, то вы распечатаете не все элементы, а только 5 первых.
Решить эту проблему можно несколькими способами:
- Если по условию вашей задачи, элементов всегда 5, или не больше 5, то вам стоит использовать std::array<std::string, 5>, в такой реализации вы не рискуете выйти за границы памяти.
- Если же количество элементов неизвестно, то можно использовать динамический массив std::vector<std::string>, таким образом вы можете использовать его метод size(), чтобы узнать текущее количество элементов.
cerr << p->persons[i];
Семантически поток std::cerr предназначен для вывода ошибок и не поддерживает буферизацию. Для вывода информационных сообщений лучше использовать поток std::cout.