深入理解C指针之---迷途指针

  一、若程序中存在迷途指针,轻则导致程序退出,重则使程序出现重大逻辑错误

    1、定义:内存已释放,指针依旧指向原始内存,这种指针就是迷途指针


    2、迷途指针和指针别名:

      1)、指针依旧指向已释放的内存,无法访问内存中的内容;

      2)、迷途指针没有指向有效对象,也称为内存过早释放;

      3)、两个指针指向同一个内存区域,称为指针别名;

      4)、使用指针别名的程序容易出现迷途指针,任意释放一个指针的内存即可,不需要每个都释放一下;

      5)、linux中使用工具valgrind,使用命令valgrind --tool=memcheck --leak-check=yes fileName检测程序fileName的内存泄露情况;

    3、代码形式:

      1)、指针依旧指向已释放的内存,无法访问内存中的内容;

int  *ptrInt1 = (int *)malloc(sizeof(int));
*ptrInt = 9;free(ptrInt1);
…
*ptrInt1 = 10;

      2)、迷途指针没有指向有效对象,也称为内存过早释放;

int  *ptrInt1 = (int *)malloc(sizeof(int));
*ptrInt = 9;
free(ptrInt1);
…
printf("%d",*ptrInt1);

      3)、两个指针指向同一个内存区域,称为指针别名;

int  *ptrInt1 = (int *)malloc(sizeof(int));
*ptrInt = 9;
…
int  *ptrInt2 = ptrInt1;
…
free(ptrInt1);
…
*ptrInt1 = 10;

      4)、使用指针别名的程序容易出现迷途指针,任意释放一个指针的内存即可,不需要每个都释放一下;

int  *ptrInt1 = (int *)malloc(sizeof(int));
*ptrInt = 9;
…
int  *ptrInt2 = ptrInt1;
…
free(ptrInt1);
…
free(ptrInt2);

      5)、linux中使用工具valgrind,使用命令valgrind --tool=memcheck --leak-check=yes fileName检测程序fileName的内存泄露情况;

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int main(int argc, char **argv)
 5 {
 6     int *ptrInt = (int *)malloc(sizeof(int) * 6);
 7     int size = 6;
 8     for(int i = 0; i < size; i++){
 9         *(ptrInt + i) = 90 + i;
10     }
11
12     for(int i = 0; i < size; i++){
13         printf("ptrInt[%d]: %d\t", i, *(ptrInt + i));
14     }
15     free(ptrInt);
16
17     return 0;
18 }

  将上述代码编译后生成test14可执行文件,使用命令:valgrind --tool=memcheck --leak-check=yes test14,结果为

 develop  …  CodeStudy  cnblogs_understanding_and_using_c_pointers  chapter2  valgrind --tool=memcheck --leak-check=yes test14
==1513== Memcheck, a memory error detector
==1513== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1513== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1513== Command: test14
==1513==
ptrInt[0]: 90   ptrInt[1]: 91   ptrInt[2]: 92   ptrInt[3]: 93   ptrInt[4]: 94   ptrInt[5]: 95   ==1513==
==1513== HEAP SUMMARY:
==1513==     in use at exit: 0 bytes in 0 blocks
==1513==   total heap usage: 2 allocs, 2 frees, 1,048 bytes allocated
==1513==
==1513== All heap blocks were freed -- no leaks are possible
==1513==
==1513== For counts of detected and suppressed errors, rerun with: -v
==1513== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

  上述结果没有发生内存泄露,若将第15行代码注释掉,重新编译,执行命令:valgrind --tool=memcheck --leak-check=yes test14,结果为

cnblogs_understanding_and_using_c_pointers  chapter2  valgrind --tool=memcheck --leak-check=yes test14 ==1908== Memcheck, a memory error detector
==1908== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1908== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1908== Command: test14
==1908==
ptrInt[0]: 90   ptrInt[1]: 91   ptrInt[2]: 92   ptrInt[3]: 93   ptrInt[4]: 94   ptrInt[5]: 95   ==1908==
==1908== HEAP SUMMARY:
==1908==     in use at exit: 24 bytes in 1 blocks
==1908==   total heap usage: 2 allocs, 1 frees, 1,048 bytes allocated
==1908==
==1908== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1908==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1908==    by 0x1086B2: main (test14.c:6)
==1908==
==1908== LEAK SUMMARY:
==1908==    definitely lost: 24 bytes in 1 blocks
==1908==    indirectly lost: 0 bytes in 0 blocks
==1908==      possibly lost: 0 bytes in 0 blocks
==1908==    still reachable: 0 bytes in 0 blocks
==1908==         suppressed: 0 bytes in 0 blocks
==1908==
==1908== For counts of detected and suppressed errors, rerun with: -v
==1908== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

  检查表明有一处内存泄露,有24个字节内存泄露,其他的请参看valgrind的帮助文档,man valgrind即可,非常方便。


  

人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。