`
javahigh1
  • 浏览: 1288166 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

内存没有初始化和内存越界的后果

 
阅读更多

如果你发现你的程序Debug版本好好的,但是Release版本会挂。那么多半你是变量没有初始化或者是内存小规模越界了。

如果你发现你的程序在调试器里好好的,独立运行会挂,那么恭喜你,99%就是变量没有初始化或者是内存越界。

这次老衲犯白痴。两件都碰上了。

上集:

首先的症状就是Release版本在调试器里跑的好好的,一到独立运行就挂了。用debugger attach到crash的进程后发现是c++ exception std::bad_alloc。基本上root cause已经确认。某个地方内存操作越界,把堆给写坏了。导致后续内存分配的时候,分配不到可以用的内存。

但是哪行代码之后的的堆被写坏了呢?邪恶的C++ exception屏蔽了这一信息。经过几个小时的纠结之后,我想起了set_new_handler这样神奇的东西。在crash的模块里设置了new的出错处理代码。

这回,终于能从call stack上看到哪里出错了。

可是,,,我发现这个crash的地方,竟然是随机的。。真是杯具。

折腾了两晚上,把很多不顺眼的代码都修改顺眼了,咦,这回crash的地方竟然是同一个地方了。真是神奇。接下来就简单了。在该位置附近插入一段代码 char* pData = malloc(1024); 很快就确定出问题的起源了:

原先我的TransformBuffer只包含了matWorld matView matProject, 后来shader里有需要用到Camera的信息,于是我就将Camera::Eye(up , pos , dir) 加到了TransformBuffer之后,于是Const Buffer的大小就是 sizeof(xTransMatrixs) + sizeof(Camera::Eye). 过了几天,我又发现,需要把Camera的near/far的信息传递到Shader里去,于是我又加了 near far等四个float到Eye后面,这回我忘记重新调整constant buffer的大小了。杯具就这样产生了。

下集:

搞定了上集的故事后,紧接着我又发现DX11的渲染器里面,Release版本独立运行竟然绘制不出任何东西来。(注:在VC里运行都是好的)。这个似乎比上集的故事更加神奇。我在Model的draw和drawPrimitive里打log,似乎一切都运行的很正常。但是屏幕上就是空空如也,除了改变背景色能起作用意外。其它都没起作用的。

也许是受前几天的影响,这次我学乖了。直接上工具,刚好试了试AMD的GPUPerfStudio,frame debugger一看,每一个多边形都画在正确的位置上.....故障很明显了:Rasterizer或者Blend的状态设置的有问题。注释一下Rasterizer或者Blend的set代码,很快将就确定了:BlendState初始化的时候,没有从xml里去读取SampleMask变量。导致SampleMask错误,FrameBuffer没有写入东西。

这两天的故事就是这样,两个故事的代价我熬了三个晚上。困啊,囧啊。

PS: 2B的AMD和2B 马维尔

2B AMD的profile程序竟然使用80做端口,囧死了。有几个人会在需要远程的情况下用80来调试的?

2B Marvell,装个Raid驱动程序竟然给我启动了个apache httpd服务。

于是两个2B就这么干上了。

分享到:
评论

相关推荐

    定位多线程内存越界问题实践总结

    valgrind可以检测多种内存问题,包括内存泄漏、未初始化的内存读取和越界写入等。使用valgrind启动程序,可以获取更详细的错误报告,但它同样没有直接指出问题的根源。 在这个过程中,开发者还尝试了其他辅助工具,...

    vector定义和初始化

    下面的示例展示了如何使用`vector`定义、初始化、插入、删除和访问元素: ```cpp #include #include int main() { std::vector<int> myVector = {1, 2, 3, 4, 5}; myVector.push_back(6); myVector.insert...

    c++内存分配1

    2. 未初始化的内存引用:分配内存后,应立即对其进行初始化,避免使用未定义的值。 3. 越界访问:特别是在数组操作中,确保索引在有效范围内,避免“多1”或“少1”的错误。 4. 内存泄漏:忘记释放内存会导致内存...

    走下神坛的内存调试器--定位多线程内存越界问题实践总结.pdf

    首先,文章介绍了Valgrind,这是一个强大的内存调试工具,能够检测程序运行时的内存管理问题,如内存泄漏、未初始化的内存读写、内存越界访问和重复释放等。Valgrind的工作原理是通过运行时检测(Runtime Checking)...

    一种利用内存保护技术实现程序踩内存的检测方法

    例如,AddressSanitizer可以在编译时插入额外的代码,对内存分配和释放进行跟踪,当检测到未初始化的内存读取、越界访问、释放后使用等情况时,会立即报告错误。 为了有效地利用内存保护技术,开发者需要遵循一些...

    C内存管理 pdf

    内存管理是计算机编程中一个至关重要的主题,尤其是在C语言中,因为C语言提供了对底层硬件的直接...遵循良好的编程实践,如检查指针有效性、正确初始化内存、小心操作数组边界、及时释放内存等,是避免内存错误的关键。

    vc 内存管理(很好的资源)

    2. 初始化内存:分配的数组和内存要立即初始化,避免使用未初始化的内存。 3. 防止越界:确保数组和指针的索引在安全范围内。 4. 配对释放:动态分配的内存必须与释放配对。 5. 设置NULL:释放内存后,将指针设为...

    GDB查找内存泄露

    Valgrind提供了一整套内存错误检测工具,包括Memcheck,它能检测内存泄露、使用未初始化的内存和内存越界等问题。LeakSanitizer是编译器插件,可以在编译时集成到程序中,提供更快速的内存泄露检测,而且无需使用GDB...

    C和c++内存详解,内存的分配分析

    此外,程序员应当对新分配的内存进行初始化,特别是数组,因为未初始化的内存可能包含任意值,这会导致程序运行的不可预测性。 数组和指针是C和C++中处理内存的基本工具,它们各有特点和使用场景。数组拥有固定大小...

    指针和内存分配详解

    内存错误是编程中常见的问题,主要包括内存分配失败、未初始化内存就使用、内存越界、内存泄漏以及野指针等。防止内存分配未成功的情况,应检查指针是否为NULL。对于未初始化的内存,应总是赋予初始值。在使用数组或...

    【IT十八掌徐培成】Java基础第03天-03.数组的定义-初始化-越界异常-Null异常.zip

    数组的初始化是分配内存并赋予初始值的过程。在Java中,有两种主要的初始化方式:静态初始化和动态初始化。静态初始化是在声明时就指定每个元素的初始值,如下所示: ```java int[] myArray = {1, 2, 3, 4, 5}; // ...

    C和C++内存管理详细介绍

    2. 内存越界访问:访问了未分配或超出分配范围的内存,可能引发程序崩溃或不稳定行为。 3. 野指针:未初始化或已经释放的指针仍被使用,可能导致不确定的结果。 4. 内存分配未成功,却使用了它:在分配内存失败后,...

    valgrind内存检测工具

    1. Memcheck:这是Valgrind的核心组件,用于检测内存错误,如未初始化的内存读取、无效的内存访问(包括读写已释放的内存)以及内存泄漏。 2. Callgrind:这是一个性能分析工具,可以收集程序的调用关系图,并分析...

    代码优化:有效使用内存 --代码优化过程中内存的有效使用

    12. **代码审查**:定期进行代码审查,检查潜在的内存问题,如未初始化的变量、越界访问等。 通过以上这些策略,开发者可以在保证程序功能的同时,显著提升其内存使用效率。在实际项目中,结合具体的编程语言特性和...

    C语言系列——C 内存管理详解

    - **内存越界**:确保数组或指针操作不过界,特别是循环中的索引。 - **内存泄漏**:确保每次`malloc/new`后都有相应的`free/delete`释放内存。 - **释放后继续使用内存**:释放内存后将指针设为NULL,防止野指针...

    内存访问错误_学习笔记

    要避免内存越界,需要在操作数组或动态分配内存时确保索引和大小的正确性,尤其是处理用户输入时要格外小心。 3. **野指针**:野指针是指指向已被释放内存的指针。释放内存后,指针仍指向原来的位置,但该位置的...

    c语言指针和内存

    1. **使用`memset`初始化内存**:可以使用`memset`函数将新分配的内存初始化为特定值,通常是0。 ```c char *p = malloc(10); memset(p, '\0', 10); ``` 2. **使用`calloc`替代`malloc`**:`calloc`函数不仅会...

    C++中内存泄露检测工具

    Memory是一款跨平台的内存检测工具,主要针对C和C++,能够检测内存泄露、越界访问和双重释放等错误。 6. Memcheck:Valgrind的子工具之一,专门用于检测C和C++程序中的内存错误,包括内存泄露。 使用这些工具时,...

    pclint内存检测工具

    它在软件开发过程中扮演着重要的角色,能够帮助程序员发现潜在的内存泄漏、未初始化的变量、越界访问等问题,从而提升代码质量和可靠性。 1. **内存泄漏检测** 内存泄漏是程序开发中的常见问题,PCLint通过跟踪...

Global site tag (gtag.js) - Google Analytics