我一直在努力学习C ++中的套接字编程,因此开发了一个基本的IRC机器人。我已经将它连接起来并正在工作,但是我确定谁已经加入了频道(即机器人本身的JOIN命令,随机用户或我)。
我在Windows 7上使用了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 << " - name\n";
std::cout << nick << " - nick\n";
//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);
}
}
我不确定为什么我会得到多余的东西&#34; (我不知道它是什么)来自我的getter,因为它只是一个返回私有变量的情况:
const char* BotDetails::getNickName() { return nickName; }
无论如何,这不是我的问题,因为我可以摆脱它(尽管它可能相当hacky)。
我的问题是,当我连接到通道进行测试时,我在分配trueNick的行上设置断点,这样我就可以看到当我逐步完成程序时会发生什么,会发生以下情况:
1)为trueNick分配值:0x10042d0f9&lt; _ZStL6ignore + 119&gt; &#34; CPlusPlusBotTest&#34;
2)为nick分配了值:&#34; CPlusPlusBotTest&#34;
3)为名称分配值:&#34; Seanharrs&#34;并且为nick分配了值:&#34; Seanharrs&#34;
这意味着当我的调试语句运行时,nick和name是相同的值。我不确定为什么将nick重新分配为与name相同的值,这不应该发生。它每次都会发生,而不仅仅是因为我的名字。我尝试使用char数组和字符串,但无济于事。我也觉得奇怪的是,trueNick从未受到影响,它只是这两个变量。任何帮助都是值得赞赏的(即使它只是一个alt /更好的方式来检查这个而不是修复,因为它可能只是我个人的一个奇怪的事情,没有其他人经历过。)
答案 0 :(得分:2)
此行导致未定义的行为:
const char *nick = string(details.getNickName()).c_str();
它将构造一个临时字符串对象并返回一个指向数据的指针。但是,暂时意味着它将被立即销毁并且指针无效。
编辑:
事实证明,OP误解了调试器显示的附加信息,并将其解释为变量的值。澄清之后,就没有必要进行转换&#34;这会导致未定义的行为,代码可能只是:
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的值已经意外地改变了#34;&#34;。它改变了,因为指针在指向已经释放的内存的意义上是无效的。额外的行
const char* pdemo = std::string(tdemo).c_str();
导致编译器重用该内存,因此值* p发生了变化。
换句话说 - 你有未定义的行为。
我的猜测是你的问题在details.getNickName();
在我看来,返回的指针并不是每次指向相同的测试。可能它有一些初始化问题,因此它第一次返回错误的值,然后再更正值。
导致未定义行为的行无法执行OP声明的转换,因此它必须是更改函数的返回值。