C語言記憶體檢測__C語言

來源:互聯網
上載者:User

https://www.codeproject.com/script/Membership/View.aspx?mid=4264280

IntroductionMemory leak has always been a part of bugs in C code where a programmer allocates memory in run time (in heap) and fails to deallocate it. And most programmers use some third party software to detect memory leak in their code.But we can write very simple code to detect memory leak in our program.Usually we allocate memory in C using malloc() and calloc() in run time and deallocate the reserved memory using free(). Sometimes we don't free the reserved memory which causes memory leak.The below method is a very simple one and helps to detect memory leak in your program.Using the CodeLet's assume you have allocated some memory in your code using malloc() and calloc() and haven't deallocated it and your code looks like below.Hide   Copy Codetest.c#include<malloc.h>int main() {    char * ptr1 = (char *) malloc (10); // allocating 10 bytes    int * ptr2 = (int *) calloc (10, sizeof(int)); // allocating 40 bytes // let sizeof int =  4 bytes)    float * ptr3 = (float *) calloc (15, sizeof(float)); // allocating 60 bytes    ............    ............    ............    free(ptr2);    return 0;}    </malloc.h>Steps to Detect Memory Leak(I have tested the code in a Linux machine using GCC. You can test the same code in Windows as well.)Step 1Now to test memory leak, just add the leak_detector_c.h file to the test file and add one line to the start of main function.Now the test code should look like below:Hide   Copy Codetest.c#include<malloc.h>#include "leak_detector_c.h"int main() {    char * ptr1;     int * ptr2;     float * ptr3;    atexit(report_mem_leak);    ptr1 = (char *) malloc (10); // allocating 10 bytes            ptr2 = (int *) calloc (10, sizeof(int)); // allocating 40 bytes // let sizeof int =  4 bytes)    ptr3 = (float *) calloc (15, sizeof(float)); // allocating 60 bytes    ............    ............    ............    free(ptr2);    return 0;}    </malloc.h>Step 2Now compile the code and run the program:Hide   Copy Code# gcc -c leak_detector_.c# gcc -c test.c# gcc -o memtest leak_detctor_c.o test.o# ./memtest# cat /home/leak_info.txt    Now you will get output as shown below:Hide   Copy CodeMemory Leak Summary-----------------------------------address : 140668936size    : 10 bytesfile    : test.cline    : 5-----------------------------------address : 140669560size    : 60 bytesfile    : test.cline    : 7-----------------------------------The output shows the file name and line number which causes the memory leak and now you can free the unallocated memory. If you have multiple source files, you can add the header file in all the files where you want to detect possible memory leak and compile the program as above.Now let's have a look into the code and see how it works.The leak_detctor_c.h file contains some macros and the preprocessor replaces the call of malloc, calloc and free functions with xmalloc, xcalloc and xfree respectively .While calling malloc(), our xmalloc() is called and we keep all information of the allocated memory (like the address, size, file name and line number) in a linked list. While the code calls the free() function, it actually calls our xfree() and we manage to do the cleanup task (remove the entry of the allocated memory from the list and free up the allocated memory).At the end of the program, we can get the unallocated memory references from the list.The line "atexit(report_mem_leak)" registers the report_mem_leak() function to be called at the end of the program and this function writes the memory leak summary into the leak_info.txt file. You can also use #pragma exit directive instead of atexit().



leak_detector_c.h

#ifndef  LEAK_DETECTOR_C_H#define  LEAK_DETECTOR_C_H#define  FILE_NAME_LENGTH      256#define  OUTPUT_FILE   "/home/leak_info.txt"#define  malloc(size)        xmalloc (size, __FILE__, __LINE__)#define  calloc(elements, size)  xcalloc (elements, size, __FILE__, __LINE__)#define  free(mem_ref)    xfree(mem_ref)struct _MEM_INFO{void*address;unsigned intsize;charfile_name[FILE_NAME_LENGTH];unsigned intline;};typedef struct _MEM_INFO MEM_INFO;struct _MEM_LEAK {MEM_INFO mem_info;struct _MEM_LEAK * next;};typedef struct _MEM_LEAK MEM_LEAK;void add(MEM_INFO alloc_info);void erase(unsigned pos);void clear(void);void * xmalloc(unsigned int size, const char * file, unsigned int line);void * xcalloc(unsigned int elements, unsigned int size, const char * file, unsigned int line);void xfree(void * mem_ref);void add_mem_info (void * mem_ref, unsigned int size,  const char * file, unsigned int line);void remove_mem_info (void * mem_ref);void report_mem_leak(void);#endif


leak_detector_c.c

#include<stdio.h>#include<malloc.h>#include<string.h>#include"leak_detector_c.h"#undefmalloc#undefcalloc#undef freestatic MEM_LEAK * ptr_start = NULL;static MEM_LEAK * ptr_next =  NULL;/* * adds allocated memory info. into the list * */void add(MEM_INFO alloc_info){MEM_LEAK * mem_leak_info = NULL;mem_leak_info = (MEM_LEAK *) malloc (sizeof(MEM_LEAK));mem_leak_info->mem_info.address = alloc_info.address;mem_leak_info->mem_info.size = alloc_info.size;strcpy(mem_leak_info->mem_info.file_name, alloc_info.file_name); mem_leak_info->mem_info.line = alloc_info.line;mem_leak_info->next = NULL;if (ptr_start == NULL){ptr_start = mem_leak_info;ptr_next = ptr_start;}else {ptr_next->next = mem_leak_info;ptr_next = ptr_next->next;}}/* * erases memory info. from the list * */void erase(unsigned pos){unsigned index = 0;MEM_LEAK * alloc_info, * temp;if(pos == 0){MEM_LEAK * temp = ptr_start;ptr_start = ptr_start->next;free(temp);}else {for(index = 0, alloc_info = ptr_start; index < pos; alloc_info = alloc_info->next, ++index){if(pos == index + 1){temp = alloc_info->next;alloc_info->next =  temp->next;free(temp);break;}}}}/* * deletes all the elements from the list */void clear(){MEM_LEAK * temp = ptr_start;MEM_LEAK * alloc_info = ptr_start;while(alloc_info != NULL) {alloc_info = alloc_info->next;free(temp);temp = alloc_info;}}/* * replacement of malloc */void * xmalloc (unsigned int size, const char * file, unsigned int line){void * ptr = malloc (size);if (ptr != NULL) {add_mem_info(ptr, size, file, line);}return ptr;}/* * replacement of calloc */void * xcalloc (unsigned int elements, unsigned int size, const char * file, unsigned int line){unsigned total_size;void * ptr = calloc(elements , size);if(ptr != NULL){total_size = elements * size;add_mem_info (ptr, total_size, file, line);}return ptr;}/* * replacement of free */void xfree(void * mem_ref){remove_mem_info(mem_ref);free(mem_ref);}/* * gets the allocated memory info and adds it to a list * */void add_mem_info (void * mem_ref, unsigned int size,  const char * file, unsigned int line){MEM_INFO mem_alloc_info;/* fill up the structure with all info */memset( &mem_alloc_info, 0, sizeof ( mem_alloc_info ) );mem_alloc_info.address = mem_ref;mem_alloc_info.size = size;strncpy(mem_alloc_info.file_name, file, FILE_NAME_LENGTH);mem_alloc_info.line = line;/* add the above info to a list */add(mem_alloc_info);}/* * if the allocated memory info is part of the list, removes it * */void remove_mem_info (void * mem_ref){unsigned short index;MEM_LEAK  * leak_info = ptr_start;/* check if allocate memory is in our list */for(index = 0; leak_info != NULL; ++index, leak_info = leak_info->next){if ( leak_info->mem_info.address == mem_ref ){erase ( index );break;}}}/* * writes all info of the unallocated memory into a file */void report_mem_leak(void){unsigned short index;MEM_LEAK * leak_info;FILE * fp_write = fopen (OUTPUT_FILE, "wt");char info[1024];if(fp_write != NULL){sprintf(info, "%s\n", "Memory Leak Summary");fwrite(info, (strlen(info) + 1) , 1, fp_write);sprintf(info, "%s\n", "-----------------------------------");fwrite(info, (strlen(info) + 1) , 1, fp_write);for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next){sprintf(info, "address : %d\n", leak_info->mem_info.address);fwrite(info, (strlen(info) + 1) , 1, fp_write);sprintf(info, "size    : %d bytes\n", leak_info->mem_info.size);fwrite(info, (strlen(info) + 1) , 1, fp_write);sprintf(info, "file    : %s\n", leak_info->mem_info.file_name);fwrite(info, (strlen(info) + 1) , 1, fp_write);sprintf(info, "line    : %d\n", leak_info->mem_info.line);fwrite(info, (strlen(info) + 1) , 1, fp_write);sprintf(info, "%s\n", "-----------------------------------");fwrite(info, (strlen(info) + 1) , 1, fp_write);}}clear();}
main.c

#include<malloc.h>#include"leak_detector_c.h"int main(){char * ptr1 = (char *)malloc(10);int * ptr2 = (int *)calloc(10, sizeof(int));float * ptr3 = (float *) calloc(15, sizeof(float));free(ptr2);atexit(report_mem_leak);return 0;}



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.