2013-04-29 78 views
1

我在這裏寫一個C pgm,它創建一個線程並處理它。爲了避免線程發生內存泄漏,我使用了pthread_cleanup_push和pthread_cleanup_pop函數,並且最後在線程函數中調用了pthread_exit。運行該程序時,出現以下錯誤。內存泄漏處理,同時終止線程C

我相信一些內存分配/免費問題在那裏。請幫助我,我怎樣才能安全地終止沒有內存泄漏的線程。下面是我的程序: -

struct str_thrd_data 
{ 
     SQLHANDLE hstmt; 
     int rc; 
     bool thrd_completed_flag; 
}; 

void * str_in_thread_call(void *in_str_arg) 
{ 
     int thrd_rc; 
     struct str_thrd_data *str_arg; 
     str_arg = in_str_arg; 

     pthread_cleanup_push(free, str_arg); 
     thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 
     if (thrd_rc != 0) 
       handle_error_en(thrd_rc, "pthread_setcancelstate"); 

     thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 
     if (thrd_rc != 0) 
       handle_error_en(thrd_rc, "pthread_setcancelstate"); 

     printf("\n*********************Normal Thread termination withing timelimit %d\n",str_arg->rc); 
     str_arg->thrd_completed_flag = true; 
     sleep(1); 
     pthread_cleanup_pop(1); 
     pthread_exit(1); 
} 

int main() 
{ 
     printf("\nPJH: New THread created.\n"); 
     pthread_attr_t tattr; 
     pthread_t th; 
     size_t mysize = 1; 

     struct str_thrd_data atd; 

     atd.hstmt = hstmt; 
     atd.rc= rc; 
     atd.thrd_completed_flag = false; 

     thrd_rc = pthread_attr_init(&tattr); 
     thrd_rc = pthread_attr_setstacksize(&tattr, mysize); 
     thrd_rc = pthread_create(&th, &tattr, &str_in_thread_call, &atd); 
     if (thrd_rc != 0) 
       handle_error_en(thrd_rc, "pthread_create"); 

     while(timeout !=0) 
     { 
       printf("%d Value of rc=%d\n",timeout, atd.rc); 
       if(atd.rc != 999) break; 
       timeout--; 
       usleep(10000); 
     } 
     rc = atd.rc; 
} 

下面是錯誤消息我得到的,運行程序時: -

*** glibc detected *** ./myprocessname: free(): invalid pointer: 0xbc8d9f34 *** 
======= Backtrace: ========= 
/lib/libc.so.6[0x5e0c65] 
/lib/libc.so.6(cfree+0x59)[0x5e4c59] 
./dcs[0x80a828a] 
/lib/libpthread.so.0[0x7c4912] 
/lib/libc.so.6(clone+0x5e)[0x64c60e] 
======= Memory map: ======== 
00558000-00573000 r-xp 00000000 fd:00 393227        /lib/ld-2.5.so 
00573000-00574000 r--p 0001a000 fd:00 393227        /lib/ld-2.5.so 
00574000-00575000 rw-p 0001b000 fd:00 393227        /lib/ld-2.5.so 
00577000-006ce000 r-xp 00000000 fd:00 393228        /lib/libc-2.5.so 
006ce000-006d0000 r--p 00156000 fd:00 393228        /lib/libc-2.5.so 
006d0000-006d1000 rw-p 00158000 fd:00 393228        /lib/libc-2.5.so 
006d1000-006d4000 rw-p 006d1000 00:00 0 
006d6000-006fd000 r-xp 00000000 fd:00 393234        /lib/libm-2.5.so 
006fd000-006fe000 r--p 00026000 fd:00 393234        /lib/libm-2.5.so 
006fe000-006ff000 rw-p 00027000 fd:00 393234        /lib/libm-2.5.so 
007a1000-007a8000 r-xp 00000000 fd:00 393417        /lib/librt-2.5.so 
007a8000-007a9000 r--p 00007000 fd:00 393417        /lib/librt-2.5.so 
007a9000-007aa000 rw-p 00008000 fd:00 393417        /lib/librt-2.5.so 
007bf000-007d5000 r-xp 00000000 fd:00 393230        /lib/libpthread-2.5.so 
007d5000-007d6000 r--p 00015000 fd:00 393230        /lib/libpthread-2.5.so 
007d6000-007d7000 rw-p 00016000 fd:00 393230        /lib/libpthread-2.5.so 
007d7000-007d9000 rw-p 007d7000 00:00 0 
007db000-007e6000 r-xp 00000000 fd:00 393252        /lib/libgcc_s-4.1.20080825.so.1 
007e6000-007e7000 rw-p 0000a000 fd:00 393252        /lib/libgcc_s-4.1.2-20080825.so.1 
007e9000-007ec000 r-xp 00000000 fd:00 393237        /lib/libdl-2.5.so 
007ec000-007ed000 r--p 00002000 fd:00 393237        /lib/libdl-2.5.so  
007ed000-007ee000 rw-p 00003000 fd:00 393237        /lib/libdl-2.5.so 
00acd000-00adf000 r-xp 00000000 fd:00 393296        /lib/libz.so.1.2.3 
00adf000-00ae0000 rw-p 00011000 fd:00 393296        /lib/libz.so.1.2.3 
08048000-0810c000 r-xp 00000000 fd:01 1517776       /home/myprocessname 
0810c000-08185000 rw-p 000c3000 fd:01 1517776       /home/myprocessname 
08185000-08215000 rw-p 08185000 00:00 0 
0857b000-08aee000 rw-p 0857b000 00:00 0         [heap] 
1ffea000-1ffeb000 ---p 1ffea000 00:00 0 
1ffeb000-3f3eb000 rwxp 1ffeb000 00:00 0 
3f3eb000-3f42c000 rw-p 3f3eb000 00:00 0 
3f42c000-3f44c000 rw-s 00000000 00:09 1570996267       /SYSV00000000 (deleted) 
3f44c000-3f48c000 rw-p 3f44c000 00:00 0 
3f48c000-3f4ac000 rw-s 00000000 00:09 1570963498       /SYSV00000000 (deleted) 
3f4ac000-3f4cc000 rw-s 00000000 00:09 1570930729       /SYSV00000000 (deleted) 
3f4cc000-3f58c000 rw-p 3f4cc000 00:00 0 
3f58c000-3f5ac000 rw-s 00000000 00:09 1570897960       /SYSV00000000 (deleted) 
3f5ac000-3f62c000 rw-p 3f5ac000 00:00 0 
3f62c000-3f64c000 rw-s 00000000 00:09 1570865191       /SYSV00000000 (deleted) 
3f64c000-3f6cc000 rw-p 3f64c000 00:00 0 
3f6cc000-3f6ec000 rw-s 00000000 00:09 1570832422       /SYSV00000000 (deleted) 
3f6ec000-3f70c000 rw-s 00000000 00:09 1570799653       /SYSV00000000 (deleted) 
3f70c000-3f72c000 rw-s 00000000 00:09 1570766884       /SYSV00000000 (deleted) 
3f72c000-3f8ec000 rw-p 3f72c000 00:00 0 
3f8ec000-3f8ed000 ---p 3f8ec000 00:00 0 
3f8ed000-5eced000 rwxp 3f8ed000 00:00 0 
5eced000-5ecee000 ---p 5eced000 00:00 0 
5ecee000-7e0ee000 rwxp 5ecee000 00:00 0Aborted (core dumped) 
+0

您應該調用'pthread_join'來代替忙線等待線程退出主線程。這也釋放了線程系統內部使用的一些數據。 – 2013-04-29 07:21:46

回答

2

你試圖釋放內存堆棧爲main功能上。那當然不起作用。

在您的pthread_create調用中,您使用&atd,這將返回一個指向main函數堆棧中的atd結構的指針。這種記憶不能也不應該被你釋放。

+0

我不想釋放結構atd。一旦完成,我想釋放線程函數str_in_thread_call使用的所有本地內存。你能告訴我如何實現它,以及我使用過的方式「pthread_cleanup_push(free,str_arg)和pthread_cleanup_pop(1)」是否正確? – CodeCodeCode 2013-04-29 07:14:14

+0

@PalLoveCoding但'str_arg'取自線程參數,它是'&atd'。 'pthread_create'不會分配新內存,它甚至不提供您傳遞的數據大小。由於線程共享內存空間,您只需將實際的指針傳遞給'pthread_create'。 – 2013-04-29 07:19:13

+0

@PalLoveCoding檢查調試器將非常容易。在'pthread_create'調用上設置一個斷點,並在線程函數上設置一個斷點。比較'&atd'和'in_str_arg'的值。你會看到他們確實是一樣的,這意味着他們都指向相同的記憶。 – 2013-04-29 07:23:38

1

上述代碼的另一個問題是thrd_rc = pthread_attr_setstacksize(&tattr, mysize);這個mysize應該是系統頁面大小的倍數,否則功能將失敗。