C ++中使用不同编译器版本的奇怪行为(String按引用传递):请参阅简单程序插图

时间:2017-01-18 15:38:09

标签: c++ string gcc pass-by-reference

我在C ++执行中面临一些奇怪的问题。我的项目很大,我在几个地方使用了引用,但我向您展示了一个可以轻松测试的问题示例。

我写了这个简单的程序,并在GCC版本下面进行了测试:v4.9.2和v5.4.0。我得到了不同的行为。使用和不使用引用时传递std :: string。在这个程序中,我只需在地图中添加两个条目,然后找到一个键的值。问题出在map :: find(..)上。无论使用何种gcc编译器版本,我都期望一致的行为。

  

GCC版本:4.9.2输出:FOUND,FOUND(在Raspberry Pi3上测试,http://cpp.sh

     

GCC版本:5.4.0输出:未找到,找不到(在Ubuntu v16.04上测试)

为什么会出现这种情况?这个程序有问题还是某个编译器错误?下面的程序应按原样编译。

// program.cpp
// Compile using: "g++ -o program program.cpp"

#include <iostream>
#include <string>
#include <map>
#include <stdio.h>
using namespace std;

std::map<const char*,int> mymap;

bool FindWithoutPassByRef(const std::string id_)
{
    const char* id = id_.c_str();

    std::map<const char*, int>::iterator it;
    it = mymap.find(id);

    if (it != mymap.end())
    {
        cout <<"FOUND";
        return true;
    }

    cout <<"NOT FOUND";
    return false;
}

bool FindWithPassByRef(const std::string& id_)
{
    const char* id = id_.c_str();

    std::map<const char*, int>::iterator it;
    it = mymap.find(id);

    if (it != mymap.end())
    {
        cout <<"\nFOUND";
        return true;
    }

    cout <<"\nNOT FOUND";
    return false;
}

int main(int argc, char *argv[])
{
    printf("gcc version: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);

    const std::string key1 = "key1";
    const std::string key2 = "key2";

    mymap[key1.c_str()] = 50;
    mymap[key2.c_str()] = 60;

    FindWithoutPassByRef(key1); // should print FOUND
    FindWithPassByRef(key1);    // should print FOUND

    cout<< endl;
}

我希望在任何gcc编译器下都可以找到FOUND和FOUND。 请参阅GCC v4.9.2 here下正常运行的示例,或在cpp.sh上添加上述代码(使用v4.9.2)。对于编译器v5.4.0,您可以在Ubuntu或其他地方进行相应的测试。

1 个答案:

答案 0 :(得分:4)

您将指针放在地图中并尝试将它们与其他指针匹配。这只比较那些指针所持有的“存储器地址”;它不会比较他们指向的东西(即你的字符串数据)。

当你的指针指向单个std::string的数据时,很可能它们是相同的指针(因为数据在同一个地方)。但是,当你的指针指向不同的字符串时,其可能性非常小。

不要在地图中放置char指针。比较实际的字符串。