Valgrind对两个缓冲区说“源和目的地在memcpy中重叠”,但是它们似乎不重叠

问题描述

| OP末尾的最后编辑 我用Valgrind测试了一个项目中使用的函数,它说“源和目标在memcpy中重叠”,并且还给我“无效读取”和“无效写入”错误。我修复了代码,以便不与这两个缓冲区重叠但没有结果。这是代码
static
int download_build_buffer(char **seq_numbered_buffer,int seq_n,int dim_payload,char *buffer) {

if(!seq_numbered_buffer)
    return 1;

/* allocates seq_numbered_buffer */
if(*seq_numbered_buffer != NULL) {
    free(*seq_numbered_buffer);
    *seq_numbered_buffer = NULL;
}
if(!(*seq_numbered_buffer = malloc((SIZE_SEQ_N + SIZE_DIM_S + dim_payload + 1) * sizeof(char))))
    return 1;

#if DEBUG_DOWNLOAD
fprintf(stderr,\"download_build_buffer %d: seq->%d,dim->%d\\n\",getpid(),seq_n,dim_payload);
#endif

/* prints sequence number in its string */
seq_n = htonl(seq_n);
if(!memcpy(*seq_numbered_buffer,&seq_n,SIZE_SEQ_N))
    return 1;
dim_payload = htonl(dim_payload);
if(!memcpy(&(*seq_numbered_buffer)[SIZE_SEQ_N],&dim_payload,SIZE_DIM_S))
    return 1;

/* creates payload -> buffer = seq_number + buffer */
if(!memcpy(&(*seq_numbered_buffer)[SIZE_SEQ_N+SIZE_DIM_S],buffer,dim_payload))
    return 1;
(*seq_numbered_buffer)[SIZE_SEQ_N+SIZE_DIM_S+dim_payload] = 0;

return 0;
}
函数调用如下:
/* allocates buffer */
if(buffer != NULL) {
    free(buffer);
    buffer = NULL;
}
assert((buffer = malloc((dim_payload+1)*sizeof(char)))
               != NULL);

/* stores bytes in buffer */
if((n = read(fd,dim_payload)) <= 0)
    break;
buffer[n] = 0;
buf_len = n;

/* increments seq_number */
seq_n = next_request;

/* creates payload -> buffer = seq_number + buffer */
if(download_build_buffer(&seq_numbered_buffer,dim_payload,buffer))
    return 1;
seq_numbered缓冲区和buffer的定义和初始化为:
char *seq_numbered_buffer = NULL,*buffer = NULL;
另外,我试图用memmove代替memcpy,但没有结果:( 我的Valgrind输出
==3921== Source and destination overlap in memcpy(0x41bb2b0,0x41bb070,131072)
==3921==    at 0x4027BD6: memcpy (mc_replace_strmem.c:635)
==3921==    by 0x8049A8D: download_build_buffer (uftp_server.c:791)
==3921==    by 0x8049F4C: server_download_file (uftp_server.c:989)
==3921==    by 0x804A4E1: data_connection_proc (uftp_server.c:1209)    
==3921==    by 0x804AEE8: main (uftp_server.c:1512)
==3921== 
==3921== Invalid read of size 4
==3921==    at 0x4027D42: memcpy (mc_replace_strmem.c:635)
==3921==    by 0x8049A8D: download_build_buffer (uftp_server.c:791)
==3921==    by 0x8049F4C: server_download_file (uftp_server.c:989)
==3921==    by 0x804A4E1: data_connection_proc (uftp_server.c:1209)
==3921==    by 0x804AEE8: main (uftp_server.c:1512)
==3921==  Address 0x41db06c is not stack\'d,malloc\'d or (recently) free\'d
==3921== 
==3921== Invalid write of size 4
==3921==    at 0x4027D44: memcpy (mc_replace_strmem.c:635)
==3921==    by 0x8049A8D: download_build_buffer (uftp_server.c:791)
==3921==    by 0x8049F4C: server_download_file (uftp_server.c:989)
==3921==    by 0x804A4E1: data_connection_proc (uftp_server.c:1209)
==3921==    by 0x804AEE8: main (uftp_server.c:1512)
==3921==  Address 0x41db2ac is not stack\'d,malloc\'d or (recently) free\'d
==3921== 
==3921== Invalid write of size 1
==3921==    at 0x8049A9C: download_build_buffer (uftp_server.c:792)
==3921==    by 0x8049F4C: server_download_file (uftp_server.c:989)
==3921==    by 0x804A4E1: data_connection_proc (uftp_server.c:1209)
==3921==    by 0x804AEE8: main (uftp_server.c:1512)
==3921==  Address 0x41db2b0 is not stack\'d,malloc\'d or (recently) free\'d
==3921== 
server_download_file 3921: download finished
--3921-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--3921-- si_code=1;  Faulting address: 0x0;  sp: 0x62af9e0c

valgrind: the \'impossible\' happened:
Killed by fatal signal
==3921==    at 0x38034171: unlinkBlock (m_mallocfree.c:244)

sched status:
running_tid=1

Thread 1: status = VgTs_Runnable
==3921==    at 0x4026864: malloc (vg_replace_malloc.c:236)
==3921==    by 0x804911B: file_release_lock (uftp_server.c:423)
==3921==    by 0x8049DE9: server_download_file (uftp_server.c:930)
==3921==    by 0x804A4E1: data_connection_proc (uftp_server.c:1209)
==3921==    by 0x804AEE8: main (uftp_server.c:1512)
万一,请问我其他信息,谢谢 编辑 在最后一次执行memcpy dim_payload之前,使用htonl()将其转换为网络格式,并将其从512传递至131072。它需要使用ntohl()返回512。     

解决方法

        
assert
中不应有副作用。当不使用它们进行编译时,它们的表达将被忽略。在这种情况下,以下可能会导致您的问题:
assert((buffer = malloc((dim_payload+1)*sizeof(char)))
           != NULL);
我将其替换为:
buffer = malloc((dim_payload+1)*sizeof(char));
assert(buffer != NULL);
哦,
sizeof(char)
始终为1,因此您可以将其删除。