具有不同编译器版本的 C++ 中的奇怪行为(通过引用传递字符串):参见简单的程序说明
Strange behavior in C++ with different compiler versions (String pass by reference): See simple program illustration
我在执行 C++ 时遇到了一些奇怪的问题。我的项目很大,我在几个地方使用了引用传递,但我向您展示了一个您可以轻松测试的问题示例。
我写了这个简单的程序,并在下面的 GCC 版本下进行了测试:v4.9.2 和 v5.4.0。我有不同的行为,尤其是。在有和没有参考的情况下传递 std::string 时。在这个程序中,我只是将两个条目添加到一个映射中并找到一个键的值。问题在于 map::find(..)。无论使用何种 gcc 编译器版本,我都希望行为一致。
GCC version: 4.9.2 output: FOUND, FOUND (tested on Raspberry Pi3, http://cpp.sh)
GCC version: 5.4.0 output: NOT FOUND, FOUND (tested on 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 编译器下都能找到并找到。
请参阅 GCC v4.9.2 here or add the above code on cpp.sh 下的示例 运行(使用 v4.9.2)。对于编译器 v5.4.0,您可以在 Ubuntu 或其他适当的地方进行测试。
您正在将指针放在地图中并尝试将它们与其他指针相匹配。这只会比较那些指针持有的 "memory address";它不比较它们指向的东西(即你的字符串数据)。
当您的指针是指向来自单个 std::string
的数据的指针时,它们是相同指针的可能性很大(因为数据位于同一位置)。但是,当您的指针指向不同的字符串时,这种可能性很小。
不要在地图中放置 char
指针。而是比较实际的字符串。
我在执行 C++ 时遇到了一些奇怪的问题。我的项目很大,我在几个地方使用了引用传递,但我向您展示了一个您可以轻松测试的问题示例。
我写了这个简单的程序,并在下面的 GCC 版本下进行了测试:v4.9.2 和 v5.4.0。我有不同的行为,尤其是。在有和没有参考的情况下传递 std::string 时。在这个程序中,我只是将两个条目添加到一个映射中并找到一个键的值。问题在于 map::find(..)。无论使用何种 gcc 编译器版本,我都希望行为一致。
GCC version: 4.9.2 output: FOUND, FOUND (tested on Raspberry Pi3, http://cpp.sh)
GCC version: 5.4.0 output: NOT FOUND, FOUND (tested on 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 编译器下都能找到并找到。 请参阅 GCC v4.9.2 here or add the above code on cpp.sh 下的示例 运行(使用 v4.9.2)。对于编译器 v5.4.0,您可以在 Ubuntu 或其他适当的地方进行测试。
您正在将指针放在地图中并尝试将它们与其他指针相匹配。这只会比较那些指针持有的 "memory address";它不比较它们指向的东西(即你的字符串数据)。
当您的指针是指向来自单个 std::string
的数据的指针时,它们是相同指针的可能性很大(因为数据位于同一位置)。但是,当您的指针指向不同的字符串时,这种可能性很小。
不要在地图中放置 char
指针。而是比较实际的字符串。