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

将void*转为vector<void*>*后程序触发越界崩溃,求问题原因

问题分析:vector访问越界崩溃原因

问题代码回顾

数据存储代码

string mystring[10] = {"key1","key2","keyN"};
for(string s: mystrings){
    vector<void*> v;
    v.push_back(this);
    v.push_back(&s);
    map.insert({s,&v});
}

定时器与回调代码

// 定时器调用
mytimer(int milliseconds, mycallback,void* (parameter of the callback));
this->mytimer(1000,MY_CALLBACK,map.at("Key1"));

// 回调函数
static void MY_CALLBACK(void*);
void MY_CALLBACK(void* args){
    auto obj = (vector<void*>*) args;
    auto key = (string*) obj->at(1);
    auto logic = (MY_CLASS *) obj->at(0);
    // some logic;
}

核心问题

你在循环中创建的vector<void*> v是循环体内的局部变量,每次循环迭代结束后,这个vector的生命周期就会终止,对应的栈内存会被系统回收或标记为可复用。你将&v插入map,本质是存储了一个野指针。

当定时器触发回调时,通过map.at("Key1")拿到的指针指向的内存已经完全失效——既不是原来的vector结构,内存内容也可能被其他数据覆盖。此时调用obj->at(0)或obj->at(1),访问的是无效内存,直接触发"out of range"错误(甚至会出现更严重的未定义行为)。

另外还有一个隐藏问题:循环中的string s同样是局部变量,你把&s存入vector,后续访问该指针时,对应的string对象也早已被销毁,同样会引发问题。

解决思路

  • 避免存储局部变量指针:改用动态分配内存(如new vector<void*>),或使用智能指针(如std::shared_ptr<std::vector<void*>>)管理对象生命周期,确保回调触发时,vector的内存仍有效。
  • 处理string指针问题:不要存储局部string的指针,改为存储string的副本,或动态分配string对象。

修改示例

string mystring[10] = {"key1","key2","keyN"};
for(const string& s: mystring){
    // 动态分配vector,延长生命周期
    auto v = new vector<void*>();
    v->push_back(this);
    // 动态分配string,存储副本避免局部变量销毁问题
    v->push_back(new string(s));
    map.insert({s, v});
}

注意:使用动态分配后,需在回调完成或不再需要时手动释放内存,避免泄漏;使用智能指针可自动管理内存,更安全。

内容的提问来源于stack exchange,提问作者Alessandro Savona

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:22:29