一个 std::string 得到一个完全出乎意料的值
A std::string gets a totally unexpected value
我的类有一个成员std::string received;
,在其构造函数中以空字符串初始化,以及一个将字符串打印到cout
的函数printReceived
。
在main()
中,创建上述类的实例,并调用printReceived
。
我没有得到一个空字符串,而是得到完全出乎意料的值(但总是相同的(:
-
如果
printReceived
是std::cout<<"Received ":<<received<<std::endl;
,我得到Received: eived:
作为输出。 -
一个字符串常量,存在于另一个类的函数中,如果此文件已链接,则未调用该类。
这从何而来?这让我很生气...所有变量都已正确初始化。我以前从未遇到过这个问题,而且我在C++中编程了很多。
这是一个完整的最小示例:
蜂窝测试.cpp
#include "A.h"
#include <iostream>
int main()
{
A s;
s.println("AT+CSQ");
return 0;
}
答.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();
};
生成文件
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:
operator+=
的优先级低于 operator+
。所以在println
中,你正在这样做:
received+=(s+'n');
这就像
received+=(s+10);
这是将指针s
增加 10 个字节,然后将生成的char*
指向的字符串附加到 received
中,并且字符串文字Recieved:
恰好存储在字符串文字AT+CSQ
之后。所以内存可能看起来像AT+CSQ Received:
,AT+CSQ
增加 10 实际上是Received:
e
。所以你有它。
将其更改为
received+=s;
received+='n';
或者或者
received = received + s + 'n';
void A::println(char* s)
{
received+=s+'n';
你显然从未处理过原始字符串。首先 - 始终被视为const char*
或std::string
- 因为修改内容是未定义的行为。其次,您的+
实际上是在执行指针算术,即received += &s['n'];
,而不是串联。主机字符串显然不足以达到 13 左右的 IIRC n
值,因此您的程序表现出未定义的行为。
如果你想在C++中使用字符串,并且你不太确定自己在做什么,请始终处理std::string
,因为这种事情不可能发生。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '