简体   繁体   English

返回std :: string时无效的指针(所以说libc)

[英]invalid pointer when returning std::string (so says libc)

I have a member function inside a mmapped-file-consuming class, that looks like this: 我在使用mmapped-file的类中有一个成员函数,如下所示:

std::string Data::GetASCIIZ(OFFSET* offsetp) const
{
  char* str = (char*)_buffer + *offsetp;  // _buffer points to mmap'd file
  *offsetp += strlen(str) + 1;
  return std::string(str);
}

(the type of 'OFFSET' is unsigned long long) (“ OFFSET”的类型为unsigned long long)

Its raison d'etre is to (a) return a std::string of the null-terminated C-string that is presumed to exist at offset *offsetp , after (b) advancing the value of *offsetp past the end of said C-string. 其存在的理由是(a)在假定(b)将*offsetp的值推进到所述C的末尾之后,返回假定为存在于偏移量*offsetp的以空终止的C字符串的std :: string。 -串。

I call this function in numerous situations, without issue. 我在很多情况下都调用此函数,没有任何问题。 However, I have recently added a new call to it, that always SIGABRTs in a peculiar way: 但是,最近我给它添加了一个新的调用,该调用始终以一种特殊的方式进行SIGABRT:

*** glibc detected *** /home/ryan/src/coolapp/out/coolapp: free(): invalid pointer: 0xb7eb165c ***

The above message is followed by a backtrace (culminating in some code within libc.so.6), and a memory map... both of which are ostensibly useful to me somehow, in debugging this issue. 上面的消息后面是回溯(最终在libc.so.6中的一些代码中)和一个内存映射...两者在某种程度上对我来说在调试此问题上都是有用的。

From debugging with GDB, I've learned that the SIGABRT doesn't actually happen inside my Data::GetASCIIZ method quoted above, but rather within the code that calls it during the right side of an assignment. 通过使用GDB进行调试,我了解到SIGABRT实际上并没有在上面引用的Data::GetASCIIZ方法内部发生,而是在赋值右侧调用它的代码内发生。 (So, I presume during the invocation of std::string's copy constructor): (因此,我假设在调用std :: string的副本构造函数期间):

[ EDIT : updated to dovetail with an expected answer from @WhozCraig] [ 编辑 :已更新为与@WhozCraig的预期答案相吻合]

struct stuff
{
  char version;
  std::string sigstring;
  // ...
};

stuff* mystuff = (stuff*)malloc(sizeof(stuff));
// ...
mystuff->sigstring = _data->GetASCIIZ(offsetp);  // SIGABRT HAPPENS AT THIS SCOPE

In this particular situation, the C-string at offset *offsetp happens to be an empty string, but I've verified that that is not consequential by temporarily modifying *offsetp to point to something else from within GDB. 在这种特殊情况下,偏移量*offsetp处的C字符串恰好是一个空字符串,但是我已经通过临时修改*offsetp指向GDB中的其他内容来验证了这是没有*offsetp

My method is marked const because it does not modify any of the internal state of the Data object. 我的方法被标记为const因为它不会修改Data对象的任何内部状态。 I am returning an object that lives on the stack, but I am not doing so by reference, and I expected the copy constructor (in the calling code) to do the right thing before that stack item was destructed. 我正在返回一个驻留在堆栈上的对象,但是我没有通过引用这样做,并且我希望复制构造函数(在调用代码中)在该堆栈项被销毁之前做正确的事情。

I have tried rewriting the GetASCIIZ method to use an explicit local, but that did not help. 我尝试重写GetASCIIZ方法以使用显式本地,但这无济于事。

Am I missing something? 我想念什么吗?

In case it is useful, here is the disassembly of the call-during-assignment where this SIGABRT happens. 如果有用,这里是SIGABRT发生时的call-during-assignment的分解。 (The '==>' is at the point of the error.) (“ ==>”位于错误点。)

424         sigstring = _data->GetASCIIZ(offsetp);
   0x0807def1 <+183>:   mov    0x8(%ebp),%eax
   0x0807def4 <+186>:   mov    0x4(%eax),%eax
   0x0807def7 <+189>:   lea    0x4(%eax),%ecx
   0x0807defa <+192>:   lea    -0x18(%ebp),%eax
   0x0807defd <+195>:   mov    0x1c(%ebp),%edx
   0x0807df00 <+198>:   mov    %edx,0x8(%esp)
   0x0807df04 <+202>:   mov    %ecx,0x4(%esp)
   0x0807df08 <+206>:   mov    %eax,(%esp)
   0x0807df0b <+209>:   call   0x809e6ee <Data::GetASCIIZ(unsigned long long*) const>
   0x0807df10 <+214>:   sub    $0x4,%esp
   0x0807df13 <+217>:   mov    -0x14(%ebp),%eax
   0x0807df16 <+220>:   lea    0x4(%eax),%edx
   0x0807df19 <+223>:   lea    -0x18(%ebp),%eax
   0x0807df1c <+226>:   mov    %eax,0x4(%esp)
   0x0807df20 <+230>:   mov    %edx,(%esp)
   0x0807df23 <+233>:   call   0x8049560 <_ZNSsaSEOSs@plt>
   0x0807df28 <+238>:   lea    -0x18(%ebp),%eax
   0x0807df2b <+241>:   mov    %eax,(%esp)
=> 0x0807df2e <+244>:   call   0x80497f0 <_ZNSsD1Ev@plt>
   0x0807e026 <+492>:   lea    -0x18(%ebp),%eax
   0x0807e029 <+495>:   mov    %eax,(%esp)
   0x0807e02c <+498>:   call   0x80497f0 <_ZNSsD1Ev@plt>
   0x0807e031 <+503>:   mov    %ebx,%eax
   0x0807e033 <+505>:   jmp    0x807e046 <CoolClass::SpiffyMethod(unsigned long long, unsigned long long, unsigned long long*)+524>
   0x0807e035 <+507>:   mov    %eax,%ebx

Your sample is as follows. 您的示例如下。

std::string Data::GetASCIIZ(OFFSET* offsetp) const
{
  char* str = (char*)_buffer + *offsetp;  // _buffer points to mmap'd file
  *offsetp += strlen(str) + 1;
  return std::string(str);
}

Shouldn't the return statement return a new STL string? return语句不应该返回新的 STL字符串吗?

std::string Data::GetASCIIZ(OFFSET* offsetp) const
{
  char* str = (char*)_buffer + *offsetp;  // _buffer points to mmap'd file
  *offsetp += strlen(str) + 1;
  return new std::string(str);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在指向包含 std::string 的 object 的指针上调用析构函数的指针无效 - Invalid pointer calling destructor on pointer to object containing std::string 将std :: chrono :: system_clock :: time_point :: min()转换为字符串时,无效的空指针错误 - Invalid null pointer error when converting std::chrono::system_clock::time_point::min() to string 通过指针更改 `std::string` 时出现分段错误 - Segmentation fault when changing `std::string` in by pointer 使用libc ++在Mac Yosemite上访问std :: string成员时出现链接错误 - link error when accessing std::string members on Mac Yosemite with libc++ 实现自定义(字符串)流时,Xcode 4.5.2 libc ++ std :: bad_cast - Xcode 4.5.2 libc++ std::bad_cast when implementing custom (string)stream 返回指向std :: pointer的指针时的ImplicitCast_错误 - ImplicitCast_ error when returning a pointer to std::list of pointers 调试从libc.so.6停止将write()写入std :: cout - debugging stalled write() to std::cout from libc.so.6 free():添加字符串时指针无效 - free(): invalid pointer when adding string C ++ 11 std :: promise从线程返回std :: string,数据指针看起来没有被移动复制 - C++11 std::promise returning std::string from thread, data pointer looks copied not moved std :: string值还是指针? - std::string value or pointer?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM