C++ 调试C+中的参数损坏+;?

C++ 调试C+中的参数损坏+;?,c++,heap,corruption,C++,Heap,Corruption,我的项目中有一个插件系统(在linux上运行),部分原因是插件有一个“run”方法,例如: void run(int argc, char* argv[]); 我打电话给我的插件,去检查我的argv数组(在做了很多其他事情之后),然后 阵列已损坏。我可以在函数顶部打印出值,它们是正确的,但不能在以后的执行中打印。显然有什么东西在腐蚀堆,但是 我不知道怎样才能准确地确定是什么在覆盖那个记忆。Valgrind帮不了我多少忙 请求的示例代码: 我的插件如下所示: void test_fileio::

我的项目中有一个插件系统(在linux上运行),部分原因是插件有一个“run”方法,例如:

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]);
  }
}
void test\u fileio::run(int-argc,char*argv[]){
bool all_passed=真;
//打印正确。
对于(int ii=0;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;
}
char**translate\u参数(字符串args、int和argc){
int计数器=0;
载体str_-vec;
//复制参数字符串以除去常量修饰符
字符arg_str[MAX_arg_LEN];
strcpy(arg_str,args.c_str());
//标记字符串,在空格上拆分
char*token=strtok(arg_str,“”);
while(令牌){
计数器++;
str_vec.push_back(令牌);
令牌=strtok(空,“”);
}
//分配数组
字符**to_return=新字符*[计数器];
用于(int ii=0;ii<计数器;ii++)
to_return[ii]=str_vec[ii];
//保存参数计数并返回
argc=计数器;
返回到_返回;
}

然后将生成的argc和argv传递给上述插件。

查找如何在调试器中使用内存访问断点。如果你有一个可靠的回购协议,这将在几秒钟内查明你的问题。在windbg中,它是:

ba w4 0x<address>
ba w4 0x

其中ba代表“访问中断”,“w4”是“写入4字节”(在64位系统上使用w8),“address”显然是您看到的地址。gdb和Visual Studio具有类似的功能。

查找如何在调试器中使用内存访问断点。如果你有一个可靠的回购协议,这将在几秒钟内查明你的问题。在windbg中,它是:

ba w4 0x<address>
ba w4 0x

其中ba代表“访问中断”,“w4”是“写入4字节”(在64位系统上使用w8),“address”显然是您看到的地址。gdb和Visual Studio具有类似的功能。

如何调用
转换参数?那是缺失的

由于
run
函数具有参数
char*argv[]
,它在调用插件中的
run
函数之前是否准备了一个指向char的指针数组

从代码判断,这看起来像是引起问题的那条线

// Allocate array char** to_return = new char*[counter]; //分配数组 字符**to_return=新字符*[计数器]; 您打算分配一个指向chars的指针,一个双指针,但代码的优先级似乎有点混淆了? 您是否尝试过这种方式:

char** to_return = new (char *)[counter]; 字符**to_return=新的(字符*)[计数器]; 另外,在如图所示的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]); 用于(int ii=0;ii<计数器;ii++) to_return[ii]=str_vec[ii]; //应该是这样吗。。。??? 用于(int ii=0;ii<计数器;ii++) to_return[ii]=strdup(str_vec[ii]); 冒着被否决的风险,因为OP没有显示如何调用
translate\u参数
,并且缺少进一步的信息……并且错误判断我的答案是否正确

希望这有帮助, 顺致敬意,
汤姆。

如何调用
翻译参数?那是缺失的

由于
run
函数具有参数
char*argv[]
,它在调用插件中的
run
函数之前是否准备了一个指向char的指针数组

从代码判断,这看起来像是引起问题的那条线

// Allocate array char** to_return = new char*[counter]; //分配数组 字符**to_return=新字符*[计数器]; 您打算分配一个指向chars的指针,一个双指针,但代码的优先级似乎有点混淆了? 您是否尝试过这种方式:

char** to_return = new (char *)[counter]; 字符**to_return=新的(字符*)[计数器]; 另外,在如图所示的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]); 用于(int ii=0;ii<计数器;ii++) to_return[ii]=str_vec[ii]; //应该是这样吗。。。??? 用于(int ii=0;ii<计数器;ii++) to_return[ii]=strdup(str_vec[ii]); 冒着被否决的风险,因为OP没有显示如何调用
translate\u参数
,并且缺少进一步的信息……并且错误判断我的答案是否正确

希望这有帮助, 顺致敬意,
Tom.

如果valgrind和代码检查没有帮助,你可以试试electric fence

如果valgrind和代码检查没有帮助,你可以试试electric fence

你可以提供一个代码示例,让我们的同事更容易理解你在做什么吗?添加了示例代码,因为这个插件非常大,所以它是框架代码,但是这给了你问题的要点。我想我们可以告诉你问题的本质是什么,但是你忽略了任何有助于问题的真正根源的东西。有一百万种不同的东西可能会破坏这个数组,但你已经漏掉了所有的代码。该死的…海报留下了…应该被标记为家庭作业…抱歉,伙计们,源代码太大了,无法完整发布。我主要是在寻找如何调试这类事情的技巧,而不是在这个例子中的具体帮助。你能提供一个代码示例,让我们其他人更容易理解你在做什么吗?添加了示例代码,它是框架性的,因为这个插件相当大,但这给了你