变量赋值覆盖其他变量的值
Variable assignment overrides value of other variable
我一直在尝试学习C++中的套接字编程,因此一直在开发一个基本的IRC机器人程序。我已经连接并运行了它,但我在确定谁加入了通道时遇到了问题(即机器人程序本身、随机用户或我的JOIN命令)。
我在Windows7上使用CLion。
我有以下代码:
//determine if message is JOIN command
if(regex_search(line, match, std::regex(R"(:([^!]*)!.*?JOIN)")))
{
//get the nickname of the bot (details.getNickName() shown in next code segment)
const char *trueNick = details.getNickName();
//reformat nickname because the following is returned from the method alone
//0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"
const char *nick = string(details.getNickName()).c_str();
//get the name of the user who joined
const char *name = match.str(1).c_str();
//debugging
std::cout << name << " - namen";
std::cout << nick << " - nickn";
//might not be the correct way to compare the two? but I'll sort that out later
if(name != nick)
{
//welcome the user
char param[1024];
sprintf(param, "%s :Hello, %s", details.getChannel(), name);
sendData("PRIVMSG", param);
}
}
我不确定为什么我从getter那里得到多余的"东西"(我不知道它是什么),因为这只是一个返回私有变量的例子:
const char* BotDetails::getNickName() { return nickName; }
无论如何,这不是我的问题,因为我可以摆脱它(尽管它可能相当棘手)。
我的问题是,当我连接到通道进行测试时,我在分配trueNick的行上设置了一个断点,这样我就可以看到在我执行程序时会发生什么,出现以下情况:
1) trueNick被分配了值:0x10042d0f9<_ZStL6ignore+119>"CPlusPlusBotTest"
2) nick被分配了值:"CPlusPlusBotTest"
3) name被赋予值:"Seanharrs",nick被赋予值"Seanharns"
这意味着当我的调试语句运行时,nick和name是相同的值。我不知道为什么nick被重新分配为与name相同的值,这不应该发生。这种情况每次都会发生,不仅仅是因为我的名字。我尝试使用char数组和字符串,但没有成功。我也觉得奇怪的是,trueNick从来没有受到影响,只有这两个变量。任何帮助都是值得感激的(即使这只是一种替代/更好的检查方式,而不是修复,因为这很可能只是我这边的一个奇怪之处,其他人都没有经历过)。
此行导致未定义的行为:
const char *nick = string(details.getNickName()).c_str();
它将构造一个临时字符串对象,并返回一个指向数据的指针。但是,临时性意味着它将被立即销毁,并且指针将无效。
编辑:
事实证明,OP误解了调试器显示的附加信息,并将其解释为变量的值。在澄清了这一点之后;转换";这会导致未定义的行为,并且代码可能只是:
const char *nick = details.getNickName();
const char *name = match.str(1).c_str();
if( strcmp(name, nick) == 0 )
{
//....
}
下面仍然显示了未定义行为的示例。
未定义行为的示例代码
考虑这个代码:
#include <iostream>
using namespace std;
int main() {
const char t[] = "0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"";
const char* pTrue = t;
const char* p = std::string(t).c_str();
std::cout << pTrue << std::endl;
std::cout << p << std::endl;
return 0;
}
它将输出(相反:它可能输出):
0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"
0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"
(ideone.com用于本例并给出了上述输出)
因此,你可能会认为这没关系。(注意:我不明白OP提到的转换)。
现在考虑这个代码:
#include <iostream>
using namespace std;
int main() {
const char tdemo[] = "Some demo text"; // Added this line
const char t[] = "0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"";
const char* pTrue = t;
const char* p = std::string(t).c_str();
const char* pdemo = std::string(tdemo).c_str(); // Added this line
std::cout << pTrue << std::endl;
std::cout << p << std::endl;
return 0;
}
它将输出(相反:它可能输出)
0x10042d0f9 <_ZStL6ignore+119> "CPlusPlusBotTest"
Some demo text
(ideone.com用于本例并给出了上述输出)
正如你所看到的,*p的值改变了";出乎意料地";。它之所以更改,是因为指针指向的内存已经释放,因此指针无效。额外的线路
const char* pdemo = std::string(tdemo).c_str();
导致编译器重用该内存,因此值*p发生了更改。
换句话说,你有未定义的行为。
我猜你的问题在details.getNickName();
内部
在我看来,返回的指针并不是每次都指向同一个测试。也许它有一些初始化问题,所以它第一次返回错误的值,然后再更正值。
导致未定义行为的行不能执行OP所声明的转换,因此它必须是更改的函数的返回值。
- C++ 成员变量被非成员函数覆盖
- 使用CIN时,字符串变量不会被覆盖
- 通过使用全局变量的函数访问在给定范围内被覆盖的变量
- 每个方法调用上都覆盖了本地变量指针
- for 循环,允许变量相互覆盖
- C 的变量覆盖
- C 覆盖成员变量
- 覆盖运算符<< 对于控制台输出不适用于成员变量
- C 多重继承,虚拟方法覆盖问题和协变量返回类型
- 提取运算符 (>>) 可以覆盖变量吗?
- C++ 在超类构造函数中运行依赖于子类覆盖的大量变量的代码的正确方法是什么?
- 如何强制 gcc 查找自己的 c++ 头文件,而不覆盖 CXX 变量
- C++ fscanf() 返回 -1 并且不覆盖变量
- 为什么引用成员变量会相互覆盖
- 变量赋值覆盖其他变量的值
- c++变量在每次循环迭代期间被覆盖
- 使用new时将覆盖变量
- 为什么作用域解析对覆盖的变量不起作用?
- 模板类函数中的静态变量被全局静态变量覆盖
- c++ std条件变量覆盖了很多共享变量