Klaus
Klaus

Reputation: 1251

A std::string gets a totally unexpected value

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):

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: 

Upvotes: 0

Views: 186

Answers (2)

Seth Carnegie
Seth Carnegie

Reputation: 75130

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

Upvotes: 6

Puppy
Puppy

Reputation: 146910

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.

Upvotes: 1

Related Questions