本文介绍了消息队列示例中的 realloc 或 free 中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里我在消息队列示例中的 realloc 或 free 中遇到了一些问题.

Here i am getting some problems in realloc or free in message queue example.

在下面的程序中,在从消息队列接收到最后一条消息时,我收到了 double free or corruption 的错误.

In below program i got error of double free or corruption at the time of last message received from the message queue.

我在消息队列中发送了 10 条消息,我在接收方端收到了 10 条消息,并且工作正常.收到每条消息后,我正在释放 buf 指针.并且每次都是免费的,但上次出现问题意味着第 10 次.它给定的错误,如 double free or corruption 在我检查它之前它是如何可能的 NULL 或不是,如果条件意味着它不是 NULL 那么它如何给出错误像这样.

I send 10 messages in message queue and i received 10 messages at receiver side and its working fine.After receiving every message i am doing free the buf pointer. and its free every time but its getting problem in last time means 10th time. Its given error like double free or corruption how its possible just before i checked it is NULL or not and its came in if condition means its not NULL then how it can give error like this.

还有一件事令我感到惊讶的是,当我运行超过 10 条消息时,它唯一给出的错误是.

And one more thing which is surprised its only given error when i run for more then 10 messages.

如果我发送 1 到 9 条消息,它工作正常.

Its working fine if i send 1 to 9 number of messages.

请让我知道我的代码中的确切问题.

Please let me know Wheres the exactly problem in my code.

发送.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;
}

接收.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

推荐答案

receive.c 中,realloc 的调用方式如下:

In receive.c, realloc should be called in the following way:

buf = realloc(buf, msgsz + sizeof(long));

这应该可以解决您的问题.

This should solve your problem.

此外,在 send.c 中,您应该在每个 msgsnd 之后调用 free 并且将数据复制到 tagmessageType 字段时,您忘记了尾随的 '\0' 字符 - 您很幸运,因为内存已清零,但这不能保证.

Besides, in send.c you should call free after each msgsnd and when copying data to tag and messageType fields you forget about the trailing '\0' character - you get lucky becouse the memory is zeroed but this is no guaranteed.

这篇关于消息队列示例中的 realloc 或 free 中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 01:45