Отладка искажения параметра в C++?
У меня есть система плагинов в моем проекте (работающая на Linux), и часть этого заключается в том, что у плагинов есть метод "run", такой как:
void run(int argc, char* argv[]);
Я вызываю свой плагин и иду, чтобы проверить мой массив argv (после выполнения множества других вещей), и массив поврежден. Я могу напечатать значения в верхней части функции, и они верны, но не позже при выполнении. Понятно, что что-то портит кучу, но я не могу понять, как именно определить, что перезаписывает эту память. Вальгринд не очень помог мне.
Пример кода по запросу:
Мой плагин выглядит примерно так:
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 затем передаются плагину, упомянутому выше.
3 ответа
Как translate_arguments
позвонить? Чего не хватает...
Подготавливает ли он массив указателей на символы перед вызовом run
функция в плагине, так как run
функция имеет параметр char *argv[]
?
Это похоже на строку, которая вызывает проблемы... судя по коду
// Выделить массив char** to_return = новый символ *[counter];
Вы намереваетесь выделить указатель на указатель на символ, двойной указатель, но, похоже, приоритет кода немного перепутан? Вы пробовали это так:
char** to_return = new (char *) [counter];
Кроме того, в вашем цикле for, как показано... вы не выделяете место для самой строки, содержащейся в векторе...?
для (int ii=0; iiРиск получить отрицательное голосование, поскольку ФП не показал, как
translate_arguments
называется и не хватает дополнительной информации.... и неправильно оценивать, если мой ответ неверен...Надеюсь, это поможет, С наилучшими пожеланиями, Том.
Узнайте, как использовать точки останова доступа к памяти с вашим отладчиком. Если у вас солидный репо, это точно определит вашу проблему в считанные секунды. В windbg это:
ba w4 0x<address>
Где ba означает "перерыв при доступе", "w4" - это "запись 4 байта" (используйте w8 в 64-битной системе), а "address" - это, очевидно, адрес, который вы видите поврежденным. GDB и Visual Studio имеют схожие возможности.
Если проверка valgrind и кода не поможет, вы можете попробовать электрический забор