std :: vector构造函数中的bad_alloc

时间:2017-06-30 12:32:13

标签: c++ vector stl

==20458== Memcheck, a memory error detector ==20458== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==20458== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==20458== Command: blaattest.app/Contents/MacOS/blaattest ==20458== --20458-- run: /usr/bin/dsymutil "blaattest.app/Contents/MacOS/blaattest" ==20458== Syscall param msg->desc.port.name points to uninitialised byte(s) ==20458== at 0x103C7434A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib) ==20458== by 0x103C73796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib) ==20458== by 0x103C6D485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib) ==20458== by 0x103E0910E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib) ==20458== by 0x103E09458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib) ==20458== by 0x100BFB9DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib) ==20458== by 0x10001BA1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld) ==20458== by 0x10001BC1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld) ==20458== by 0x1000174A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld) ==20458== by 0x100017440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld) ==20458== by 0x100016523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld) ==20458== by 0x1000165B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld) ==20458== Address 0x10488d62c is on thread 1's stack ==20458== in frame #2, created by task_set_special_port (???:) ==20458== --20458-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option --20458-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times) --20458-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times) UNKNOWN workq_ops option 128 ==20458== valgrind: Unrecognised instruction at address 0x103a60b50. ==20458== at 0x103A60B50: _dispatch_kq_init (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A5E8FB: _dispatch_client_callout (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A5E8B8: dispatch_once_f (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A60A90: _dispatch_kq_update (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A620CD: _dispatch_kevent_resume (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A6203D: _dispatch_source_kevent_resume (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A61E85: _dispatch_source_kevent_register (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103A71651: _dispatch_queue_resume_finalize_activation (in /usr/lib/system/libdispatch.dylib) ==20458== by 0x103DB13C0: _notify_lib_init (in /usr/lib/system/libsystem_notify.dylib) ==20458== by 0x103DB19AB: notify_register_dispatch (in /usr/lib/system/libsystem_notify.dylib) ==20458== by 0x102A108F6: __96-[_CFXPreferences(SourceAdditions) withSourceForIdentifier:user:byHost:container:cloud:perform:]_block_invoke_2 (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation) ==20458== by 0x103A5E8FB: _dispatch_client_callout (in /usr/lib/system/libdispatch.dylib) ==20458== Your program just tried to execute an instruction that Valgrind ==20458== did not recognise. There are two possible reasons for this. ==20458== 1. Your program has a bug and erroneously jumped to a non-code ==20458== location. If you are running Memcheck and you just saw a ==20458== warning about a bad jump, it's probably your program's fault. ==20458== 2. The instruction is legitimate but Valgrind doesn't handle it, ==20458== i.e. it's Valgrind's fault. If you think this is the case or ==20458== you are not sure, please let us know and we'll try to fix it. ==20458== Either way, Valgrind will now raise a SIGILL signal which will ==20458== probably kill your program. 有一个构造函数,其中传递std::vector的单个参数应该使用size_type count默认构造的元素调整向量的大小。但是,以下代码在转换错误后失败并出现count异常:

bad_alloc

当我查看调试器时,我可以看到第二个向量构造函数发生了错误的转换:

#include <vector>

struct Inner {
  int foo;
  char buf[256];
};

template <typename Type>
struct Outer
{
  typedef std::vector<Inner> BufContainer;
  typedef typename BufContainer::size_type BufIndex;
  BufContainer bufs1;
  BufContainer bufs2;
  const BufIndex BUFCOUNT = 32;

  Outer() :
    bufs1(32),       // fine
    bufs2(BUFCOUNT)  // bad_alloc
  { }
};

int main() {
  Outer<int> outer;
}

#13 0x0000000000400bf1 in Outer<int>::Outer (this=0x7ffdc59570c0) at wtf.cc:22 22 bufs2(BUFCOUNT) (gdb) down #12 0x0000000000400d6e in std::vector<Inner, std::allocator<Inner> >::vector (this=0x7ffdc59570d8, __n=140727918359008, __a=...) at /usr/local/gcc-4.9.1/include/c++/4.9.1/bits/stl_vector.h:278 278 : _Base(__n, __a) (gdb) list 273 * This constructor fills the %vector with @a __n default 274 * constructed elements. 275 */ 276 explicit 277 vector(size_type __n, const allocator_type& __a = allocator_type()) 278 : _Base(__n, __a) 279 { _M_default_initialize(__n); } (gdb) print __n $1 = 140727918359008 只是来自std::vector::size_type的typedef。我不明白为什么我定义的常量size_t会导致构造函数中的滚动值,并且会感谢任何帮助我找到我所遗漏的明显事物的人。

1 个答案:

答案 0 :(得分:31)

BUFCOUNT不是static,这意味着它是一个实例数据成员(就像bufs1bufs2等。非静态数据成员按顺序初始化它们在类中的声明。这意味着bufs1bufs2将在 BUFCOUNT之前初始化bufs2的初始化因此使用as -yet-unitialised value BUFCOUNT(换句话说,具有未定义的行为)。

由于让每个Outer对象在其中存储相同的BUFCOUNT整数没有任何意义,因此您可能希望BUFCOUNT为静态。