变量赋值会覆盖其他变量的值

时间:2016-01-09 07:57:28

标签: c++

我一直在努力学习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 /更好的方式来检查这个而不是修复,因为它可能只是我个人的一个奇怪的事情,没有其他人经历过。)

1 个答案:

答案 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声明的转换,因此它必须是更改函数的返回值。

相关问题