0

realloc or freeここでは、メッセージキューの例でいくつかの問題が発生しています。

double free or corruption以下のプログラムでは、メッセージキューから最後にメッセージを受信したときにエラーが発生しました。

メッセージキューで10個のメッセージを送信し、受信者側で10個のメッセージを受信しましたが、正常に機能しています。すべてのメッセージを受信した後、私はbufポインタを解放しています。毎回無料ですが、前回の問題は10回目です。double free or corruption私がそれをチェックする直前にそれがどのように可能であるNULLか、そして条件がそのNULLではないことを意味する場合にそれがどのように発生したかなどの与えられたエラーは、どのようにこのようなエラーを与えることができますか?

そして、私が10を超えるメッセージを実行したときに、その唯一のエラーに驚いたもう1つのことがあります。

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
4

1 に答える 1

-1

receive.c では、次の方法で realloc を呼び出す必要があります。

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

これで問題が解決するはずです。

さらに、send.c では、各 msgsnd の後に free を呼び出す必要があり、データをフィールドにコピーするときにtagmessageType末尾の文字を忘れてしまいます'\0'。メモリがゼロになるので幸運ですが、これは保証されません。

于 2012-06-26T08:53:33.673 に答える