[笔记]C++内存相关

1. new和delete相关:

(1)new和delete成对使用,有new,必然要有delete。delete的作用是回收一块用new分配的内存,也就是释放内存。没用new分配的内存,不能用delete来释放。有new必须要有delete,不然一定会造成内存泄漏。

(2)delete一块内存,只能delete一次,不可以delete多次,否则报告异常或者是产生未预测的情况。一旦delete了这个指针,那这个指针就不能再继续使用了。当然,可以给delete传递一个空指针,这样确实能delete指针(空指针)多次。但delete一个空指针多次并没有什么实际意义。

(3)在delete一个指针后把该指针设置为空(p = nullptr;)。因为一个指针即便被delete,该指针中依然保存着它所指向的那块动态内存的地址,此时该指针叫悬空指针(程序员不能再操作这个指针所指向的内存),那么如果给该指针一个nullptr,表示该指针不指向任何内存。

2.内存场常见问题

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

//动态内存泄漏
static void mem_leak1(void)
{
    char *p = malloc(1);
}

//资源泄漏,如文件描述符未关闭
static void mem_leak2(void)
{
    FILE *fp = fopen("test.txt", "w");
}

//动态内存越界
static void mem_overrun1(void)
{
    char *p = malloc(1);
    *(short*)p = 2;
    free(p);
}

//数组越界
static void mem_overrun2(void)
{
    char array[5];
    strcpy(array, "hello");
}

//动态内存double free
static void mem_double_free(void)
{
    char *p = malloc(1);
    free(p);
    free(p);
}

//使用野指针
static void mem_free_wild_pointer(void)
{
    char *p;
    free(p);
}

int main()
{
    mem_leak1();
    mem_leak2();
    mem_overrun1();
    mem_overrun2();
    mem_double_free();
    mem_free_wild_pointer();
    return 0;
}

3.使用valgrind工具包,对内存问题的检测和定位 

执行命令:

valgrind --track-fds=yes --leak-check=full --undef-value-errors=yes ./mem_test

输出: 

==2326== Memcheck, a memory error detector
==2326== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2326== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==2326== Command: ./mem_test
==2326==
/* 此处检测到了动态内存的越界,提示Invalid write*/
==2326== Invalid write of size 2
==2326== at 0x80484B4: mem_overrun1 (in /home/fgao/works/test/a.out)
==2326== by 0x8048553: main (in /home/fgao/works/test/a.out)
==2326== Address 0x40211f0 is 0 bytes inside a block of size 1 alloc'd
==2326== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==2326== by 0x80484AD: mem_overrun1 (in /home/fgao/works/test/a.out)
==2326== by 0x8048553: main (in /home/fgao/works/test/a.out)
==2326==
 /* 此处检测到了double free的问题,提示Invalid Free */
==2326== Invalid free() / delete / delete[]
==2326== at 0x40057F6: free (vg_replace_malloc.c:325)
==2326== by 0x8048514: mem_double_free (in /home/fgao/works/test/a.out)
==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)
==2326== Address 0x4021228 is 0 bytes inside a block of size 1 free'd
==2326== at 0x40057F6: free (vg_replace_malloc.c:325)
==2326== by 0x8048509: mem_double_free (in /home/fgao/works/test/a.out)
==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)
==2326==
/* 此处检测到了未初始化变量的问题 */
==2326== Conditional jump or move depends on uninitialised value(s)
==2326== at 0x40057B6: free (vg_replace_malloc.c:325)
==2326== by 0x804853C: mem_free_wild_pointer (in /home/fgao/works/test/a.out)
==2326== by 0x8048562: main (in /home/fgao/works/test/a.out)
==2326==
 /* 此处检测到了非法使用野指针 */
==2326== Invalid free() / delete / delete[]
==2326== at 0x40057F6: free (vg_replace_malloc.c:325)
==2326== by 0x804853C: mem_free_wild_pointer (in /home/fgao/works/test/a.out)
==2326== by 0x8048562: main (in /home/fgao/works/test/a.out)
==2326== Address 0x4021228 is 0 bytes inside a block of size 1 free'd
==2326== at 0x40057F6: free (vg_replace_malloc.c:325)
==2326== by 0x8048509: mem_double_free (in /home/fgao/works/test/a.out)
==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)
==2326==
==2326==
/*此处检测到了文件指针资源的泄漏,下面提示说有4个文件描述符在退出时仍是打开的描述符0、1、2无须关心,通过报告,可以发现程序中自己明确打开的文件描述符没有关闭
*/
==2326== FILE DESCRIPTORS: 4 open at exit.
==2326== Open file descriptor 3: test.txt
==2326== at 0x68D613: __open_nocancel (in /lib/libc-2.12.so)
==2326== by 0x61F8EC: __fopen_internal (in /lib/libc-2.12.so)
==2326== by 0x61F94B: fopen@@GLIBC_2.1 (in /lib/libc-2.12.so)
==2326== by 0x8048496: mem_leak2 (in /home/fgao/works/test/a.out)
==2326== by 0x804854E: main (in /home/fgao/works/test/a.out)
==2326==
==2326== Open file descriptor 2: /dev/pts/4
==2326== <inherited from parent>
==2326==
==2326== Open file descriptor 1: /dev/pts/4
==2326== <inherited from parent>
==2326==
==2326== Open file descriptor 0: /dev/pts/4
==2326== <inherited from parent>
==2326==
==2326==
/* 堆信息的总结:一共调用了4次alloc,4次free。之所以正好相等,是因为上面有一个函数少了free,有一个函数正好又多了一个free */
==2326== HEAP SUMMARY:
==2326== in use at exit: 353 bytes in 2 blocks
==2326== total heap usage: 4 allocs, 4 frees, 355 bytes allocated
==2326==
/* 检测到一字节的内存泄漏 */
==2326== 1 bytes in 1 blocks are definitely lost in loss record 1 of 2
==2326== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==2326== by 0x8048475: mem_leak1 (in /home/fgao/works/test/a.out)
==2326== by 0x8048549: main (in /home/fgao/works/test/a.out)
==2326==
/* 内存泄漏的总结 */
==2326== LEAK SUMMARY:
==2326== definitely lost: 1 bytes in 1 blocks
==2326== indirectly lost: 0 bytes in 0 blocks
==2326== possibly lost: 0 bytes in 0 blocks
==2326== still reachable: 352 bytes in 1 blocks
==2326== suppressed: 0 bytes in 0 blocks
==2326== Reachable blocks (those to which a pointer was found) are not shown.
==2326== To see them, rerun with: --leak-check=full --show-reachable=yes
==2326==
==2326== For counts of detected and suppressed errors, rerun with: -v
==2326== Use --track-origins=yes to see where uninitialised values come from
==2326== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 12 from 8)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值