我正在尝试将一个字符串附加到另一个字符串。我声明了两个全局字符串变量 -
string grid_filename = "grids/";
string 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)
我打印出字符串的两个地址,它们都没有匹配,一个valgrind就是0字节。我在这里缺少什么?
我相信这会导致我的第二个错误,因为我将grid_filename传递给另一个通过tcp连接发送字符串的函数。 Valgrind告诉我
==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)
有谁可以向我解释问题是什么?任何帮助,将不胜感激。如果需要,我可以提供更多有关代码的信息。
答案 0 :(得分:0)
关于你的第一个错误:我们在valgrind中有误报。检查documentation以禁止这些,特别是如果它们没有指向您的代码(并且您已检查它们实际上不会导致问题)
答案 1 :(得分:0)
注意:这不是回复,这不是代码审查网站......但实际上我无法盯着这一点走开。
首先,一些真正有助于工具箱的功能:
// 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);
}
这对实际问题没什么帮助,因为你没有显示产生错误的代码。