我正在尝试在堆上创建一块内存并使用memcpy将一些数据复制到它,但memcpy会产生一个分段错误。我觉得我已经分配了足够的内存,但似乎写入无效。我无法理解为什么会这样。 创建和memcpy发生的代码如下 我将缓冲区大小分配为(response_length + sizeof(USHORT)),因为我正在复制响应的前两个字节中的长度。
typedef std::vector<UCHAR> RESPONSE_BUFFER;
typedef TimedHashMap<int, RESPONSE_BUFFER*> TimeResponseHashMap;
TimeResponseHashMap* inner_pending_response_map;
std::map<int, TimeResponseHashMap* > outer_pending_response_map;
bool
C_NORTH_WORKER_THREAD::bSaveFragmentResponse
(
int s16SessionID, int s16MessageID, UCHAR * pResponse,
USHORT response_length, VXN_PTR* const vxnptr)
{
try
{
RESPONSE_BUFFER* pResp_buffer = new RESPONSE_BUFFER(response_length+sizeof(USHORT)); //1156
memset(&pResp_buffer[0],0,(response_length+sizeof(USHORT))); //1157
memcpy(&pResp_buffer[0],&response_length,sizeof(USHORT)); //1158
memcpy((&pResp_buffer[0])+sizeof(USHORT),pResponse,response_length); //1159
}
//some more code for further processiong.
inner_pending_response_map->Insert((int)s16MessageID, pResp_buffer, expirytime); //Line 1167
if ( retval != E_SUCCESS )
{
printf("Insert failed\n");
return HD_COMMUNICATION_ERROR;
}
outer_pending_response_map.insert(make_pair((int)s16SessionID, inner_pending_response_map));
}
插入函数的定义:
template <typename Key, typename ElementObject>
THM_ERROR TimedHashMap<Key, ElementObject>::Insert(const Key& k, const ElementObject& e, const Time& expiry_time)
{
// first, check the size of the hash map to ensure there is room
/*
if ( size_ == MAX_SIZE_ )
{
return E_MAP_IS_FULL;
}
*/
// now, try to put 'e' into the map
try
{
// does k already exist in the hash map?
typename hash_map<Key, BaseElement_*, dw_hash<Key>, dw_equal_to<Key> >::iterator itr;
itr = h_->find(k);
if ( itr != h_->end() )
{
return E_DUPLICATE_KEY;
}
// create a base element object to insert into the timeout queue map
// If the expiry_time is the greatest in queue, insert time is O(1).
// (http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4)
TimeoutQueue_itr_t tq_node;
tq_node = tq_.insert(tq_.end(), make_pair(expiry_time, k));
if (tq_.end() == tq_node)
{
return E_INTERNAL_ERROR;
}
BaseElement_* be = new BaseElement_(e, tq_node);
if ( !be )
{
return E_INTERNAL_ERROR;
}
h_->insert(std::make_pair(k, be));
debugprintfMT(MSGCAT_DEBUG, MSGSUB_OK,"Insert: %x", be);
++size_;
} catch ( ... )
{
return E_INTERNAL_ERROR;
}
// finally assert that the same number of items
// in the queue are in the hash map
if ( size_ != tq_.size() )
{
return E_INTERNAL_ERROR;
}
return E_SUCCESS;
}
Valgrind报告如下:
Invalid write of size 1
==3260== at 0x6DECB1E: memcpy (mc_replace_strmem.c:482)
==3260== by 0x804E76E: C_NORTH_WORKER_THREAD::bSaveFragmentResponse(int, int, unsigned char*, unsigned short, VXN_PTR*) (norththread.cpp:1159)
==3260== by 0x805062B: C_NORTH_WORKER_THREAD::ReceiveResponseFromHost(VXN_PTR*&,unsigned char*, unsigned short&) (norththread.cpp:606)
==3260== by 0x8085653: HostWorkerThread::IncomingResponse() (workerthread.cpp:577)
==3260== by 0x80862D7: HostWorkerThread::Main() (workerthread.cpp:255)
==3260== by 0x8086684: HostWorkerThread::SpawnThread(void*) (workerthread.cpp:183)
==3260== by 0x391831: start_thread (in /lib/libpthread-2.5.so)
==3260== by 0x303E0D: clone (in /lib/libc-2.5.so)
==3260== Address 0x7abd894 is 4 bytes inside a block of size 15 free'd
==3260== at 0x6DEA51D: free (vg_replace_malloc.c:325)
==3260== by 0x2B5867: tzset_internal (in /lib/libc-2.5.so)
==3260== by 0x2B616C: tzset (in /lib/libc-2.5.so)
==3260== by 0x2BA8C5: strftime_l (in /lib/libc-2.5.so)
==3260== by 0x2FFFFE: __vsyslog_chk (in /lib/libc-2.5.so)
==3260== by 0x300549: syslog (in /lib/libc-2.5.so)
==3260== by 0x807DBFC: debugprintfMT(int, int, char const*, ...) (hostdefs.cpp:44)
==3260== by 0x805C017: Tracer::Tracer(char const*) (hostdefs.h:167)
==3260== by 0x805C6B9: TimedHashMap<int, FragmentWrapper*>::Find(int const&,FragmentWrapper*&) (timedhashmap.h:389)
==3260== by 0x8051C08: C_NORTH_WORKER_THREAD::SendRequestToHost(VXN_PTR*)(norththread.cpp:318)
==3260== by 0x8085DA4: HostWorkerThread::IncomingRequest(VXN_PTR*)(workerthread.cpp:479)
==3260== by 0x80863B2: HostWorkerThread::Main() (workerthread.cpp:285)
--3260-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--3260-- si_code=1; Faulting address: 0xD8AFF74; sp: 0x4c99dc8
GDB回溯:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf784a400 (LWP 6549)]
0x0029bc7e in _int_malloc () from /lib/libc.so.6
(gdb)
(gdb)
(gdb)
(gdb)
(gdb)
(gdb) backtrace
#0 0x0029bc7e in _int_malloc () from /lib/libc.so.6
#1 0x0029de97 in malloc () from /lib/libc.so.6
#2 0xf7fb84d7 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#3 0x0806101d in TimedHashMap<int, std::vector<unsigned char, std::allocator<unsigned char> >*>::Insert (this=0x80b6848, k=@0xf784976c, e=@0xf7849750,
expiry_time=...)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/include/../include/timedhashmap.h:354
#4 0x0804e798 in C_NORTH_WORKER_THREAD::bSaveFragmentResponse (
this=0x80b43a0, s16SessionID=48094, s16MessageID=3,
pResponse=0xf7c56124 "`\003", response_length=48, vxnptr=0x0)
at /home/FBML7HR/SrcCode/vxnservers/fdchost/north/src/norththread.cpp:1167
#5 0x0805062c in C_NORTH_WORKER_THREAD::ReceiveResponseFromHost (
this=0x80b43a0, vxnptr=@0xf784994c, response=0xf7c56124 "`\003",
response_length=@0xf784994a)
at /home/FBML7HR/SrcCode/vxnservers/fdchost/north/src/norththread.cpp:606
#6 0x08085654 in HostWorkerThread::IncomingResponse (this=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:577
#7 0x080862d8 in HostWorkerThread::Main (this=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:255
#8 0x08086685 in HostWorkerThread::SpawnThread (thread_argument=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:183
#9 0x00391832 in start_thread () from /lib/libpthread.so.0
---Type <return> to continue, or q <return> to quit---
#10 0x00303e0e in clone () from /lib/libc.so.6
(gdb)
任何提示都会有所帮助。谢谢!!
答案 0 :(得分:3)
std::vector
对象本身不是一块内存。只有一些class
或struct
可能持有指针到这样的块。因此,您无法直接复制到矢量对象上。要访问其后备内存,请在其上使用下标运算符:
UCHAR *memBuf = &pResp_Buffer[0];
然后您可以使用该指针访问原始内存。