C++ Vector返回NULL值问题:getAudioStreams传参后数据为空
解决std::vector<WCHAR*>返回空值的作用域问题
问题核心:你遇到的是典型的栈内存作用域失效导致野指针问题。extractName函数返回的是栈上定义的数组o_progName,当函数执行完毕后,这片栈内存会被系统回收复用。因此getAudioStreams函数内打印时内存还未被覆盖,能看到有效数据,但回到主函数时,vector中存储的指针已经指向无效内存,表现为空值。
解决方案一:使用std::wstring(推荐,无需手动管理内存)
直接用C++标准库的宽字符串类型替代原始指针,从根源避免野指针和内存泄漏问题:
Main.cpp
std::vector<std::wstring> names; mvc.getAudioStreams(names); for (int i = 0; i < names.size(); i++) { printf("Main I: %d | %ls\n", i, names.at(i).c_str()); }
MainVolumeControl.cpp
void MainVolumeControl::getAudioStreams(std::vector<std::wstring>& o_streams) { ... int nSessionCount = 5; for (int n = 0; n < nSessionCount; n++) { ... WCHAR wsImageName[MAX_PATH + 1]; DWORD nSize = MAX_PATH; if (QueryFullProcessImageNameW(hProcess, NULL, wsImageName, &nSize)) { printf("\nImage: %ls\n", wsImageName); std::wstring progName = extractName(wsImageName); printf("Prog: %ls\n", progName.c_str()); o_streams.push_back(progName); } ... } ... printf("\n"); for (int i = 0; i < o_streams.size(); i++) { printf("I: %d | %ls\n", i, o_streams.at(i).c_str()); printf("\n"); } } std::wstring MainVolumeControl::extractName(WCHAR i_imageName[]) { constexpr u_int LEN_IMAGE_MAX = MAX_PATH + 1; WCHAR o_progName[LEN_IMAGE_MAX]; ... // 提取文件名的逻辑不变 return std::wstring(o_progName); }
解决方案二:手动分配堆内存(需注意释放)
如果必须使用原始指针,可以在extractName中用堆内存存储字符串,使用完后记得手动释放:
修改后的extractName函数
WCHAR* MainVolumeControl::extractName(WCHAR i_imageName[]) { constexpr u_int LEN_IMAGE_MAX = MAX_PATH + 1; WCHAR* o_progName = new WCHAR[LEN_IMAGE_MAX]; // 堆内存分配 ... // 提取文件名的逻辑不变 return o_progName; }
Main.cpp中使用后释放内存
std::vector<WCHAR*> names; mvc.getAudioStreams(names); for (int i = 0; i < names.size(); i++) { printf("Main I: %d | %ls\n", i, names.at(i)); delete[] names.at(i); // 释放堆内存 } names.clear();
注意:这种方式容易遗漏内存释放,引发内存泄漏,所以优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者Open-Analysis
相关产品推荐
相关产品推荐

