2012-06-26 70 views
0

在這裏,我在消息隊列示例中得到realloc or free中的一些問題。錯誤在realloc或在消息隊列示例中免費

在下面的程序中,我收到了從消息隊列收到的最後一條消息時的錯誤double free or corruption

我在消息隊列中發送了10條消息,並且我在接收方收到了10條消息,它的工作正常。 收到每條消息後,我都會釋放指針buf。並且每次都是免費的,但上一次遇到問題意味着第10次。它給出的錯誤,如double free or corruption它如何可能只是之前我檢查它是NULL或不,它來了,如果條件意味着它不是NULL,那麼它如何可以給這樣的錯誤。

還有一件事讓我感到驚訝,那就是當我跑超過10條信息時,它唯一給出的錯誤。

它工作正常,如果我發送1到9個消息。

請讓我知道Wheres確切的問題在我的代碼中。

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 
[email protected]:~/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

在'8'開始'msgsz'而不是'sizeof(struct my_msgbuf)'開始的是什麼? – dasblinkenlight

+0

@dasblinkenlight感謝您的建議,我會在我的代碼中做。 – user1089679

回答

-1

在receive.c,realloc的應以下列方式被稱爲:

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

這應該解決您的問題。

此外,在send.c你應該叫各的msgsnd後自由和複製數據時tagmessageType字段,你忘了尾隨'\0'角色 - 你幸運becouse內存歸零,但是這是沒有保證的。