Std :: string получает совершенно неожиданное значение - PullRequest
0 голосов
/ 06 сентября 2011

Мой класс имеет член std::string received;, инициализированный пустой строкой в ​​своем конструкторе, вместе с функцией printReceived, которая печатает строку в cout.

В main() создается экземпляр вышеуказанного класса и вызывается printReceived.

Вместо получения пустой строки я получаю совершенно неожиданные значения (но всегда одинаковые):

  • Если printReceived равно std::cout<<"Received ":<<received<<std::endl;, я получу

    Received: eived: как вывод.

  • Строковая константа, присутствующая в функции другого класса , которая не называется , если этот файл связан.

Откуда это могло взяться? Это меня бесит ... Все переменные правильно инициализированы. У меня никогда раньше не было этой проблемы, и я много программировал на C ++.

Вот полный минимальный пример:

CellularTest.cpp

#include "A.h"

#include <iostream>

int main()
{
    A s;

    s.println("AT+CSQ");

    return 0;
}

a.cpp

#include "A.h"

A::A()
: received("")
{
}
void A::println(char* s)
{
    received+=s+'\n';
    treatReceived();
}
void A::treatReceived()
{
    std::cout<<"Received: "<<received<<std::endl;
}

хиджры

#include <iostream>
#include <string>

class A
{
    public:
        A();
        void println(char* s);
    private:
        std::string received;
        void treatReceived();
};

Makefile

CellularTest: CellularTest.o CellularTest.cpp A.o
    g++ CellularTest.o A.o -o CellularTest

CellularTest.o: CellularTest.cpp

A.o: A.cpp A.h

clean:
    rm *.o
    rm CellularTest

Вывод, который я получаю:

Received: eived: 

Ответы [ 2 ]

6 голосов
/ 06 сентября 2011

operator+= имеет более низкий приоритет, чем operator+. Итак, в println вы делаете это:

received+=(s+'\n');

Что похоже на

received+=(s+10);

который увеличивает значение указателя s на 10 байт, а затем добавляет строку, на которую указывает результирующий char* - received, и строковый литерал Recieved: будет сохранен сразу после строкового литерала AT+CSQ. Таким образом, память может выглядеть как AT+CSQ\0Received: \0, а увеличение AT+CSQ на 10 на самом деле e в Received:. Итак, вот оно.

Измените это на

received+=s;
received+='\n';

или альтернативно

received = received + s + '\n';
1 голос
/ 06 сентября 2011
void A::println(char* s)
{
    received+=s+'\n';

Вы явно никогда не имели дело с примитивными строками.Во-первых, всегда принимайте как const char* или std::string - потому что это неопределенное поведение для изменения содержимого.Во-вторых, ваша + фактически выполняет арифметику указателей , то есть received += &s['\n'];, , а не конкатенацию.Строка хоста явно недостаточно велика для значения \n, которое составляет 13 или около того, IIRC, и поэтому ваша программа демонстрирует неопределенное поведение.

Если вы хотите использовать строки в C ++, и выне очень уверенный в том, что вы делаете, всегда заключает сделку std::string, потому что такого рода вещи невозможны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...