1

我正在尝试在堆上创建一块内存并使用 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)

任何提示都会有所帮助。谢谢!!

4

1 回答 1

3

一个std::vector对象本身并不是一块内存。它只是一些classstruct可能持有指向这样一个块的指针。因此,您不能直接复制到矢量对象上。为了访问其后备内存,请在其上使用下标运算符:

UCHAR *memBuf = &pResp_Buffer[0];

然后,您可以使用该指针访问原始内存。

于 2014-08-26T20:47:07.340 回答