开始尝试使用valgrind

10/09/09 10:14:23 PM
Magic

刚刚看到csdn上面有个帖子在推荐里面,标题和地址如下:
一段小代码,是否出现了野指针? 请大家发表一下对野指针理解!(希望能Show出代码)
http://topic.youkuaiyun.com/u/20090208/20/122a108f-b8a0-4dfc-bdea-3206804b0ffb.html?87197如下

于是我在自己的机器上面测试了一下
我的机器配置如下:
Target: i486-linux-gnu
Thread model: posix
gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
valgrind 3.4.1
gnu make 3.81

/*******************************************************************************
 *  /file    wildpointer.cc
 *  /brief   ref the url below
 *  http://topic.youkuaiyun.com/u/20090208/20/122a108f-b8a0-4dfc-bdea-3206804b0ffb.html?87197
 *  /date    10/09/2009 08:37:59 PM
 *  /author  Magic(CHD-ZYP), magicpang@gmail.com
 *  /company SECRET
 ******************************************************************************/


#include    <cstdlib>
#include    <cstdio>

void  son_fun(int &num, float **p)
{
    *p = new float[num];
}

void mo_fun(int &num, float **pm, float *pn)
{
    float *m_ptemp;

    *pm = new float[num];
//    *pm = new float[5]; 
    son_fun(num, &m_ptemp);

    for(int k = 0; k < num; k++)
    {
        *pm[k] = m_ptemp[k];
    }
    delete []m_ptemp;    
}


int main ( int argc, char *argv[] )
{
    int     num = 5;
    float   *pf;
    float   *nothing = NULL;

    mo_fun(num, &pf, nothing);

    return EXIT_SUCCESS;
}

Makefile如下

CPP = g++

FLAG = -g -Wall
VALFLAG = --leak-check=full --show-reachable=yes


TARGET = wildpointer


$(TARGET): wildpointer.o
    $(CPP) wildpointer.o -o $(TARGET)

wildpointer.o: wildpointer.cc
    $(CPP) $(FLAG) -c wildpointer.cc


.PHONY: clean

clean:
    @find . -type f -executable | xargs rm
    @rm -f *.o

run: $(TARGET)
    ./$(TARGET)

check: $(TARGET)
    valgrind $(VALFLAG) ./$(TARGET)

运行make check
valgrind给的输出如下
为了把这个输出加到下面用了下面的方法
使用valgrind的选项--log-file=<fname>
cat <fname> >> wildpointer.txt

valgrind --leak-check=full --show-reachable=yes ./wildpointer
==30832== Memcheck, a memory error detector.
==30832== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==30832== Using LibVEX rev 1884, a library for dynamic binary translation.
==30832== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==30832== Using valgrind-3.4.1-Debian, a dynamic binary instrumentation framework.
==30832== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==30832== For more details, rerun with: -v
==30832==
==30832== My PID = 30832, parent PID = 28002.  Prog and args are:
==30832==    ./wildpointer
==30832==
==30832== Invalid write of size 4
==30832==    at 0x8048564: mo_fun(int&, float**, float*) (wildpointer.cc:29)
==30832==    by 0x80485BF: main (wildpointer.cc:41)
==30832==  Address 0x5 is not stack'd, malloc'd or (recently) free'd
==30832==
==30832== Process terminating with default action of signal 11 (SIGSEGV)
==30832==  Access not within mapped region at address 0x5
==30832==    at 0x8048564: mo_fun(int&, float**, float*) (wildpointer.cc:29)
==30832==    by 0x80485BF: main (wildpointer.cc:41)
==30832==  If you believe this happened as a result of a stack overflow in your
==30832==  program's main thread (unlikely but possible), you can try to increase
==30832==  the size of the main thread stack using the --main-stacksize= flag.
==30832==  The main thread stack size used in this run was 8388608.
==30832==
==30832== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 1)
==30832== malloc/free: in use at exit: 40 bytes in 2 blocks.
==30832== malloc/free: 2 allocs, 0 frees, 40 bytes allocated.
==30832== For counts of detected errors, rerun with: -v
==30832== searching for pointers to 2 not-freed blocks.
==30832== checked 93,252 bytes.
==30832==
==30832==
==30832== 20 bytes in 1 blocks are still reachable in loss record 1 of 2
==30832==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
==30832==    by 0x8048509: son_fun(int&, float**) (wildpointer.cc:16)
==30832==    by 0x8048541: mo_fun(int&, float**, float*) (wildpointer.cc:25)
==30832==    by 0x80485BF: main (wildpointer.cc:41)
==30832==
==30832==
==30832== 20 bytes in 1 blocks are still reachable in loss record 2 of 2
==30832==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
==30832==    by 0x8048528: mo_fun(int&, float**, float*) (wildpointer.cc:23)
==30832==    by 0x80485BF: main (wildpointer.cc:41)
==30832==
==30832== LEAK SUMMARY:
==30832==    definitely lost: 0 bytes in 0 blocks.
==30832==      possibly lost: 0 bytes in 0 blocks.
==30832==    still reachable: 40 bytes in 2 blocks.
==30832==         suppressed: 0 bytes in 0 blocks.


第一个错误
==30832== Invalid write of size 4
==30832==    at 0x8048564: mo_fun(int&, float**, float*) (wildpointer.cc:29)
==30832==    by 0x80485BF: main (wildpointer.cc:41)
==30832==  Address 0x5 is not stack'd, malloc'd or (recently) free'd
在文档中对这种错误的描述是
This happens when your program reads or writes memory at a place which Memcheck reckons it shouldn't
memcheck可以检测程序读写不属于程序的内存
对应的wildpointer.cc:29
        *pm[k] = m_ptemp[k];
这个就是要理解“指针的指针”,以及*和[]的优先级了
猜测这个代码的本意是(*pm)[k] = m_ptemp[k]或者写成*(*pm + k) = m_ptemp[k];

修补了上面这个错误之后,再次运行make check,只有一个错误
|| ==31459== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
|| ==31459==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
|| ==31459==    by 0x8048528: mo_fun(int&, float**, float*) (wildpointer.cc:23)
|| ==31459==    by 0x80485C2: main (wildpointer.cc:41)

这种错误就是malloc/new之后却没有对应的释放了。

### 使用 Valgrind 在 Windows 上进行内存调试 Valgrind 是一套强大的工具集,主要用于 Linux 平台上的程序调试和性能分析。然而,在 Windows 系统上直接运行 Valgrind 并不被官方支持[^1]。这是因为 Valgrind 的设计依赖于对底层操作系统行为的精确模拟,而这种功能在 Windows 和 Linux 之间存在显著差异。 尽管如此,开发者可以通过以下方法间接实现类似的功能: #### 方法一:使用 Cygwin 或 MinGW 工具链 Cygwin 提供了一个兼容层,允许部分 Unix/Linux 软件在 Windows 下运行。理论上可以尝试编译 Valgrind 来适配 Cygwin 环境,但实际上这通常非常复杂且可能失败。更实际的方法是利用 MinGW 编译器构建跨平台的应用程序,并将其移植到 Linux 中测试,从而充分利用 Valgrind 的能力[^2]。 #### 方法二:借助 WSL (Windows Subsystem for Linux) WSL 是微软提供的一种轻量级虚拟化技术,能够在 Windows 系统中运行原生 Linux 应用程序。安装并配置好 WSL 后,可以直接下载并安装 Valgrind 到该环境中。以下是具体操作步骤: 1. 安装最新版本的 WSL 及其对应的 Linux 发行版(如 Ubuntu)。 2. 更新包管理器并安装 Valgrind: ```bash sudo apt update && sudo apt install valgrind ``` 3. 将目标可执行文件复制至 WSL 文件系统内,或者通过交叉编译生成适合 Linux 的二进制文件。 4. 执行如下命令启动 Valgrind 分析: ```bash valgrind --tool=memcheck ./your_program.exe ``` 此方式不仅简单易行,而且能够保留完整的 Valgrind 功能特性[^3]。 #### 方法三:替代方案 - Visual Studio 自带诊断工具 如果无法满足上述条件,则推荐考虑 Microsoft Visual Studio 集成开发环境所提供的内置内存泄漏检测机制作为备选解决方案之一。它同样具备发现未释放资源的能力,并针对 Windows 特定场景进行了优化调整[^4]。 需要注意的是,虽然 VEX 技术确实构成了 Valgrind 核心组成部分的一部分,用于监控非法内存访问等问题[^5],但在当前讨论范围内并不直接影响我们探讨的内容。 ```cpp // 示例代码片段展示如何配合 GDB 使用 Valgrind 进行动态分析 #include <iostream> int main() { int* ptr = new int[10]; delete[] ptr; // 正确释放动态数组 std::cout << "Memory properly managed." << std::endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值