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

Variable assignment overrides value of other variable

本文关键字:变量 覆盖 赋值 其他      更新时间:2023-10-16

我一直在尝试学习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&lt_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所声明的转换,因此它必须是更改的函数的返回值。