You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:15:42