我的项目中有一个插件系统(在 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的和代码检查不帮助你可以尝试电子围栏

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top