Valgrind жалуется на string.append (string) - PullRequest
1 голос
/ 28 марта 2012

Я пытаюсь добавить одну строку в другую. Я объявляю две глобальные строковые переменные -

string grid_filename = "grids/";
string rest;

Тогда у меня есть функция для получения аргументов командной строки. Всякий раз, когда пользователь вводит имя файла в аргумент командной строки, оно должно быть сохранено в rest, а затем rest добавляется к grid_filename.

else if(strcmp(temp.substr(0,16).c_str(), "--grid-filename=") == 0) {
    rest = temp.substr(16,strlen(temp.c_str())-16);
    grid_filename.append(rest);   //line 74!
}

Теперь, когда я запускаю свой код, valgrind выдаёт мне эту ошибку -

==5602==  Address 0x45fdc30 is 0 bytes after a block of size 32 alloc'd
==5602==    at 0x402641D: operator new(unsigned int) (vg_replace_malloc.c:255)
==5602==    by 0x43039F7: std::string::_Rep::_S_create(unsigned int, unsigned int,     std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14)
==5602==    by 0x4304C77: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14)
==5602==    by 0x4304DA6: std::string::reserve(unsigned int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14)
==5602==    by 0x43053E9: std::string::append(std::string const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14)
==5602==    by 0x804D5AE: get_command_line_args(int, char**) (main.cpp:74)
==5602==    by 0x804F138: main (main.cpp:244)

Я распечатываю два адреса строк, и ни один из них не совпадает с тем, что, по словам Вальгринда, составляет 0 байтов. Что мне здесь не хватает?

Я считаю, что это приводит к моей второй ошибке, потому что я передаю grid_filename другой функции, которая отправляет строку по TCP-соединению. Вальгринд говорит мне

==5660== Syscall param socketcall.send(msg) points to unaddressable byte(s)
==5660==    at 0x404A9B1: send (socket.S:64)
==5660==    by 0x804F7C8: main (main.cpp:364)

Может кто-нибудь объяснить мне, в чем проблема? Любая помощь будет оценена. Я могу предоставить больше о коде, если это необходимо.

Ответы [ 2 ]

0 голосов
/ 28 марта 2012

Примечание: это не ответ, это не сайт проверки кода ... но на самом деле я не могу смотреть на это и уйти.

Во-первых, некоторые функцииэто действительно поможет в наборе инструментов:

// Some free functions (because there are too many string types)
inline char const* c_str(std::string const& s) { return s.c_str(); }
inline size_t size(std::string const& s) { return s.size(); }

inline char const* c_str(char const* s) { return s; }
inline size_t size(char const* s) { return std::strlen(s); }

template <size_t N>
char const* c_str(char const (&s)[N]) { return s; }
template <size_t N>
size_t size(char const (&s)[N]) { return N - 1; }

// A helper function (lowest common denominator)
inline bool beginsWith(char const* big, size_t const bigSize,
                       char const* small, size_t const smallSize)
{
  if (bigSize < smallSize) { return false; }
  return std::memcmp(big, small, smallSize) == 0;
}

// The actual function, doing the adaptation from the various forms of string
template <typename T, typename U>
bool beginsWith(T& big, U& small) {
    return beginsWith(c_str(big), size(big), c_str(small), size(small));
}

// same with endsWith

И тогда вы можете переписать код довольно эффективно (без дополнительного выделения памяти) и с большей читабельностью:

static std::string const GridFilenameOpt = "--grid-filename=";

// ...
else if (beginsWith(temp, GridFilenameOpt)) {
    grid_filename.append(temp, GridFilenameOpt.size(), std::string::npos);
}

Что не будеточень помогите по актуальному вопросу, так как вы не показываете код, выдающий ошибку.

0 голосов
/ 28 марта 2012

О вашей первой ошибке: у нас были ложные срабатывания в валгринде. Проверьте документацию , чтобы подавить их, особенно если они не указывают на ваш код (и вы убедились, что они на самом деле не вызывают проблем)

...