Условный переход valgrind с символами * и & lt; & lt; оператор

Я кодирую свою версию класса String, но Вальгринд скулит о моей реализации << оператор для моей строки. Ошибка в неправильная линия, если я печатаю char за char, это прекрасно работает.

Где я не прав?

Ошибка Valgrind:

== 2769 == Условный переход или перемещение зависит от неинициализированных значений

== 2769 == в 0x4C2AC28: strlen (в /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

== 2769 == по 0x4ECAD60: std :: basic_ostream>& станд :: оператор<< > (std :: basic_ostream>&, char const *) (в /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)

== 2769 == по 0x400BD5: оператор<<(Станд :: ostream&Строка&) (string.cpp: 22)

== 2769 == по 0x400AAC: main (main.cpp: 12)

мой << оператор для строки:

ostream & operator << (ostream & o, String & inS) {
o << inS._pData << " "; // the wrong line
return o;
}

мой String учебный класс:

class String {
public:
unsigned _size;
char *   _pData;
String();
String(const char* inCString);
};

Конструктор (для char*):

String::String(const char* inCString) {
_size = strlen(inCString);
_pData = new char[_size + 1];
strncpy(_pData, inCString, _size);
}

main.cpp:

int main(int, char**) {
String s1("hello");
cout << s1;
return 0;
}

3

Решение

Я не рекомендую использовать такие строки, как это.

Тем не менее, виновник здесь:

strncpy(_pData, inCString, _size+1);

Или, альтернативно, сохраните символ завершения NUL вручную:

_pData[_size] = 0;

При отсутствии символа NUL-завершения операция вывода будет продолжать выполняться после конца строки. (Поведение может выглядеть нормально, так как символ может быть нулевым, в зависимости от компилятора, опций и т. Д.)

Подсказка:

  • рассмотреть возможность использования стиля C ++ вместо C API
  • если ты должен использовать C-стиль char*по крайней мере использовать stdrup а также free
  • если вы настаиваете на выполнении NUL-завершенных строк, подумайте о том, чтобы написать на C ++ также:

    #include <iostream>
    #include <vector>
    
    class String
    {
    public:
    std::vector<char> _data;
    String();
    String(const char* inCString);
    };
    
    std::ostream & operator << (std::ostream & o, String const& inS)
    {
    o.write(inS._data.data(), inS._data.size());
    return o << ' ';
    }
    
    String::String(const char* inCString)
    {
    for (const char* it=inCString; it && *it; ++it)
    _data.push_back(*it);
    }
    
    int main(int, char**)
    {
    String s1("hello");
    std::cout << s1;
    return 0;
    }
    
10

Другие решения

Потому что вы не можете написать нулевой байт в конце. Тебе нужно:

strncpy(_pData, inCString, _size + 1);
//                              ^^^^

Вы должны всегда прочитайте инструкцию очень осторожно с n-версии строковых функций Си, поскольку все они имеют слегка различную семантику.

1

Обратите внимание, что вы явно не инициализируете свои элементы данных, вы присваиваете им значение:

…для инициализации вы должны изменить на:

String::String(const char* inCString) :
_size(strlen(inCString)),
_pData(new char[_size + 1])
{
strncpy(_pData, inCString, _size);
}
-1