题
我的项目中有一个插件系统(在 Linux 上运行),其中一部分是插件有一个“运行”方法,例如:
void run(int argc, char* argv[]);
我正在打电话给我的插件,然后去检查我的ARGV数组(在做了很多其他内容之后),并且该数组已损坏。我可以在函数顶部打印出这些值,它们是正确的,但在稍后的执行过程中则不然。显然,有些事情正在损坏堆,但是我丢失了如何尝试固定覆盖该记忆的内容。Valgrind 并没有帮助我太多。
根据请求的示例代码:
我的插件看起来像这样:
void test_fileio::run(int argc, char* argv[]) {
bool all_passed = true;
// Prints out correctly.
for (int ii=0; ii < argc; ii++) {
printf("Arg[%i]: %s\n", ii, argv[ii]);
}
<bunch of tests snipped for brevity>
// Prints out inccorrectly.
for (int ii=0; ii < argc; ii++) {
printf("Arg[%i]: %s\n", ii, argv[ii]);
}
}
它链接到一个将其公开给 python 的系统,因此我可以将这些插件作为 python 函数调用。因此,我将一个字符串参数传递给我的 python 函数,然后将其分解:
char** translate_arguments(string args, int& argc) {
int counter = 0;
vector<char*> str_vec;
// Copy argument string to get rid of const modifier
char arg_str[MAX_ARG_LEN];
strcpy(arg_str, args.c_str());
// Tokenize the string, splitting on spaces
char* token = strtok(arg_str, " ");
while (token) {
counter++;
str_vec.push_back(token);
token = strtok(NULL, " ");
}
// Allocate array
char** to_return = new char*[counter];
for (int ii=0; ii < counter; ii++)
to_return[ii] = str_vec[ii];
// Save arg count and return
argc = counter;
return to_return;
}
然后将生成的 argc 和 argv 传递给上面提到的插件。
解决方案
如何 translate_arguments
接到电话吗?那就是失踪了……
在调用之前是否准备了一个指向字符的指针数组 run
插件中的函数,因为 run
函数有参数 char *argv[]
?
从代码来看,这看起来像是造成麻烦的行
// Allocate array char** to_return = new char*[counter];
您打算分配一个指向字符指针的指针,一个双指针,但看起来代码的优先级有点混乱?你有没有尝试过这样的方法:
char** to_return = new (char *)[counter];
另外,在如图所示的 for 循环中...您没有为向量中包含的字符串本身分配空间...?
for (int ii=0; ii < counter; ii++) to_return[ii] = str_vec[ii]; // Should it be this way...??? for (int ii=0; ii < counter; ii++) to_return[ii] = strdup(str_vec[ii]);
冒着被否决的风险,因为 OP 没有展示如何 translate_arguments
被称为并缺乏进一步的信息......并且误判我的答案是否不正确......
希望这对汤姆有帮助,汤姆。
其他提示
查找如何使用内存访问断点与调试。如果你有一个坚实的回购,这将在几秒钟内找出你的问题。在WinDbg中,它是:
ba w4 0x<address>
其中BA代表“对获得突破”,“W4”是“写4个字节”(64位系统上使用W8)和“地址”显然你看到损坏的地址。 GDB和Visual Studio具有类似能力。
如果Valgrind的和代码检查不帮助你可以尝试电子围栏