我在消息队列示例中的realloc or free
中遇到了一些问题。
在下面的程序中,我从消息队列收到最后一条消息时收到double free or corruption
错误。
我在消息队列中发送了10条消息,我在接收方收到10条消息并且工作正常。
收到我正在执行的每条消息后,释放buf
指针。它每次都是免费的,但上次提出问题意味着第10次。它给出的错误如double free or corruption
在我检查它之前它是如何可能的NULL
或者它是否进入,如果条件意味着它不是NULL,那么它是如何给出这样的错误。
还有一件令我惊讶的是,当我收到超过10条消息时,它只发出错误。
如果我发送1到9个消息,它的工作正常。
请让我知道我的代码中的确切问题。
send.c
/*filename : send.c
*To compile : gcc send.c -o send
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define SEPRATOR 0X03
struct my_msgbuf
{
long mtype; /* Message type, must be > 0 */
char tag[10];
char messageType[5];
int messageNumber;
char sender[64];
char formdata[1]; /* Some compilers allow `char mtext[0]` */
};
int main(void)
{
int msqid;
key_t key;
static int count = 0;
int sperator = 3;
int run = 1;
if ((key = ftok("send.c", 'B')) == -1)
{
perror("ftok");
exit(1);
}
printf("send.c Key is = %d\n", key);
if ((msqid = msgget(key, 0644 | IPC_CREAT)) == -1)
{
perror("msgget");
exit(1);
}
printf("Enter lines of text, ^D to quit:\n");
printf("Size of strcuture == %ld\n",sizeof (struct my_msgbuf));
while (run)
{
count++;
/* Put string in a temporary place */
char tempformdata[1024];
char tempSender[64];
snprintf(tempformdata, sizeof (tempformdata), "%d%cHi hello test message here%c%d%cHi hello test message here%c%d%cHi hello test message here",count,SEPRATOR,SEPRATOR,count,SEPRATOR,SEPRATOR,count,SEPRATOR);
snprintf(tempSender, sizeof (tempSender), "TESTMEM%cTESTMEM%cTESTMEM",SEPRATOR,SEPRATOR);
/* +1 for the terminating '\0' */
size_t msgsz1 = strlen(tempformdata) + 1;
//size_t msgsz2 = strlen(tempDestination) + 1;
size_t msgsz2 = strlen(tempSender) + 1;
/* Allocate structure, and memory for the string, in one go */
struct my_msgbuf *buf = malloc(sizeof (struct my_msgbuf) + msgsz1);
/* Set up the message structure */
buf->mtype = 1;
memcpy(buf->tag,"TAGVALUES",8);
memcpy(buf->messageType,"FORM",4);
buf->messageNumber = 5;
memcpy(buf->formdata, tempformdata, msgsz1);
memcpy(buf->sender, tempSender, strlen(tempSender));
/* And send the message */
msgsnd(msqid, buf, (sizeof (struct my_msgbuf) + msgsz1- sizeof(long)), 0);
if (count == 11)
run = 0;
usleep(1000000);
}
if (msgctl(msqid, IPC_RMID, NULL) == -1)
{
perror("msgctl");
exit(1);
}
return 0;
}
receive.c
/* filename : receive.c
* To compile : gcc receive.c -o receive
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct my_msgbuf
{
long mtype; /* Message type, must be > 0 */
char tag[10];
char messageType[5];
int messageNumber;
char sender[64];
char formdata[1]; /* Some compilers allow `char mtext[0]` */
};
int main(void)
{
size_t msgsz = 8;
struct my_msgbuf *buf = NULL;
int msqid;
key_t key;
if ((key = ftok("send.c", 'B')) == -1)
{ /* same key as send.c */
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, 0644)) == -1)
{ /* connect to the queue */
perror("msgget");
exit(1);
}
printf("test: ready to receive messages, captain.\n");
for (;;)
{
/* Allocate if `buf` is NULL, otherwise reallocate */
buf = realloc(buf, msgsz);
/* Receive message */
ssize_t rsz = msgrcv(msqid, buf, msgsz, 1, 0);
if (rsz == -1)
{
if (errno == E2BIG)
msgsz += 8; /* Increase size to reallocate and try again */
else
{
perror("msgrcv");
break;
}
}
else
{
/* Can use `buf->mtext` as a string, as it already is zero-terminated */
printf("Received message of length %d bytes\n", rsz);
printf("\tReceived Tag value is : %s \n",buf->tag);
printf("\tReceived Message Type value is : %s \n",buf->messageType);
printf("\tReceived Message Number value is : %d \n",buf->messageNumber);
printf("\tReceived destinations value is : %s \n",buf->sender);
printf("\tReceived form Data Value is : %s \n",buf->formdata);
if(buf!=NULL)
{
printf("\nFree Done in Else\n");
free(buf);
printf("\nFree Done in Else 2 \n");
printf("test \n");
buf = NULL;
}
}
}
return 0;
}
输出:
test: ready to receive messages, captain.
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 1Hi hello test message here1Hi hello test message here1Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 2Hi hello test message here2Hi hello test message here2Hi hello test message here
Free Done in Else
Free Done in Else 2
test
.
.
.
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 9Hi hello test message here9Hi hello test message here9Hi hello test message here
Free Done in Else
Free Done in Else 2
test
msgrcv: Identifier removed
quipment@ubuntu:~/main/IPC/message_queue$ ./receive
test: ready to receive messages, captain.
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 1Hi hello test message here1Hi hello test message here1Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 2Hi hello test message here2Hi hello test message here2Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 3Hi hello test message here3Hi hello test message here3Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 4Hi hello test message here4Hi hello test message here4Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 5Hi hello test message here5Hi hello test message here5Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 6Hi hello test message here6Hi hello test message here6Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 7Hi hello test message here7Hi hello test message here7Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 8Hi hello test message here8Hi hello test message here8Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 175 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 9Hi hello test message here9Hi hello test message here9Hi hello test message here
Free Done in Else
Free Done in Else 2
test
Received message of length 178 bytes
Received Tag value is : TAGVALUE
Received Message Type value is : FORM
Received Message Number value is : 5
Received destinations value is : TESTMEMTESTMEMTESTMEM
Received form Data Value is : 10Hi hello test message here10Hi hello test message here10Hi hello test message here
Free Done in Else
*** glibc detected *** ./receive: double free or corruption (!prev): 0x0000000001b17010 ***
======= Backtrace: =========
/lib/libc.so.6(+0x775b6)[0x7f5faf6435b6]
/lib/libc.so.6(cfree+0x73)[0x7f5faf649e83]
./receive[0x400986]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f5faf5eac4d]
./receive[0x400719]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:11 5374010 /home/quipment/main/IPC/message_queue/receive
00600000-00601000 r--p 00000000 08:11 5374010 /home/quipment/main/IPC/message_queue/receive
00601000-00602000 rw-p 00001000 08:11 5374010 /home/quipment/main/IPC/message_queue/receive
01b17000-01b38000 rw-p 00000000 00:00 0 [heap]
7f5fa8000000-7f5fa8021000 rw-p 00000000 00:00 0
7f5fa8021000-7f5fac000000 ---p 00000000 00:00 0
7f5faf3b5000-7f5faf3cb000 r-xp 00000000 08:01 2228303 /lib/libgcc_s.so.1
7f5faf3cb000-7f5faf5ca000 ---p 00016000 08:01 2228303 /lib/libgcc_s.so.1
7f5faf5ca000-7f5faf5cb000 r--p 00015000 08:01 2228303 /lib/libgcc_s.so.1
7f5faf5cb000-7f5faf5cc000 rw-p 00016000 08:01 2228303 /lib/libgcc_s.so.1
7f5faf5cc000-7f5faf746000 r-xp 00000000 08:01 2231881 /lib/libc-2.11.1.so
7f5faf746000-7f5faf945000 ---p 0017a000 08:01 2231881 /lib/libc-2.11.1.so
7f5faf945000-7f5faf949000 r--p 00179000 08:01 2231881 /lib/libc-2.11.1.so
7f5faf949000-7f5faf94a000 rw-p 0017d000 08:01 2231881 /lib/libc-2.11.1.so
7f5faf94a000-7f5faf94f000 rw-p 00000000 00:00 0
7f5faf94f000-7f5faf96f000 r-xp 00000000 08:01 2231874 /lib/ld-2.11.1.so
7f5fafb4b000-7f5fafb4e000 rw-p 00000000 00:00 0
7f5fafb6b000-7f5fafb6e000 rw-p 00000000 00:00 0
7f5fafb6e000-7f5fafb6f000 r--p 0001f000 08:01 2231874 /lib/ld-2.11.1.so
7f5fafb6f000-7f5fafb70000 rw-p 00020000 08:01 2231874 /lib/ld-2.11.1.so
7f5fafb70000-7f5fafb71000 rw-p 00000000 00:00 0
7fffab732000-7fffab747000 rw-p 00000000 00:00 0 [stack]
7fffab796000-7fffab797000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
答案 0 :(得分:-1)
在receive.c中,应按以下方式调用realloc:
buf = realloc(buf, msgsz + sizeof(long));
这可以解决您的问题。
此外,在send.c中,你应该在每个msgsnd之后免费拨打电话,当你将数据复制到tag
和messageType
字段时,你会忘记尾随的'\0'
字符 - 你很幸运因为内存归零,但无法保证。