使用std::transform生成std::pair时触发段错误的原因及修复
问题分析与修复:std::transform触发段错误
问题原因
你的代码里std::transform的输出迭代器用了pairs.begin(),但此时pairs是一个空的vector——它没有任何已分配的元素空间,迭代器指向的是无效内存地址。transform会尝试将newP返回的pair赋值给这个迭代器指向的位置,直接导致非法内存访问,触发段错误。从栈回溯里的this=0x0也能看出来,程序正试图对空指针执行字符串赋值操作。
修复方案
有两种可靠的修复方式,根据你的需求选择:
方式1:提前为目标容器分配空间
在调用std::transform之前,调用resize为pairs分配和源容器vec相同数量的元素空间:
#include <string> #include <vector> #include <utility> #include <algorithm> // 显式包含std::transform所需头文件 std::pair<std::string, std::string> newP( const std::string& foo) { return std::make_pair(std::string("Foo"), std::string("Bar")); } int main() { std::vector<std::string> vec; std::vector<std::pair<std::string, std::string>> pairs; vec.push_back("Hello, "); vec.push_back("World!"); pairs.resize(vec.size()); // 提前分配足够空间 std::transform(vec.cbegin(), vec.cend(), pairs.begin(), newP); }
方式2:使用std::back_inserter自动插入元素
std::back_inserter会返回一个插入迭代器,它会自动调用push_back将新元素添加到目标容器中,不需要提前分配空间。这种方式更灵活,尤其适合不确定最终元素数量的场景,但需要包含<iterator>头文件:
#include <string> #include <vector> #include <utility> #include <algorithm> #include <iterator> // 包含std::back_inserter所需头文件 std::pair<std::string, std::string> newP( const std::string& foo) { return std::make_pair(std::string("Foo"), std::string("Bar")); } int main() { std::vector<std::string> vec; std::vector<std::pair<std::string, std::string>> pairs; vec.push_back("Hello, "); vec.push_back("World!"); std::transform(vec.cbegin(), vec.cend(), std::back_inserter(pairs), newP); }
额外注意
你的原始代码缺少<algorithm>头文件——std::transform定义在此,虽然部分编译器会间接包含,但显式包含是良好的编程习惯,能避免移植性问题。
内容的提问来源于stack exchange,提问作者abbe
相关产品推荐
相关产品推荐

