开发者

A std::string gets a totally unexpected value

开发者 https://www.devze.com 2023-04-02 09:04 出处:网络
My class has a member std::string received;, initialized at an empty string in its constructor, along with a function printReceived that prints the string to cout.

My class has a member std::string received;, initialized at an empty string in its constructor, along with a function printReceived that prints the string to cout.

In main(), an instance of the above class is created, and printReceived is called.

Instead of getting an empty string, I get totally unexpected values (but always the same):

  • If printReceived is std::cout<<"Received ":<<received<<std::endl;, I get

    Received: eived: as output.

  • A string constant present in a function of another class which is not called, if this file is linked.

Where could that come from ? It's getting me mad... All variables are correctly initialized. I've never had this problem before, and I've programmed a lot in C++.

Here is a complete minimal example as asked:

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;
}

A.h

#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

The output I get is:

Received: eived: 


operator+= has lower precedence than operator+. So in println, you're doing this:

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

Which is like

received+=(s+10);

Which is incrementing the pointer s by 10 bytes and then appending the string pointed to by the resulting char* to received, and the string literal Recieved: is happening to be stored just after the string literal AT+CSQ. So memory might look like AT+CSQ\0Received: \0 and incrementing AT+CSQ by 10 is actually the e in Received:. So there you have it.

Change that to

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

Or alternatively

received = received + s + '\n';


void A::println(char* s)
{
    received+=s+'\n';

You've clearly never dealt with primitive strings. Firstly- always take as a const char* or std::string - because it's undefined behaviour to modify the contents. Secondly, your + is actually performing pointer arithmetic, i.e., received += &s['\n'];, not concatenation. The host string is clearly not large enough for the value of \n which is 13 or so, IIRC, and therefore your program exhibits Undefined Behaviour.

If you want to use strings in C++, and you're not extremely sure of what you're doing, always deal in std::string, because it's impossible for this sort of thing to happen.

0

精彩评论

暂无评论...
验证码 换一张
取 消