现在的位置: 首页 > 综合 > 正文

osip释放栈区对象的深思 :_ASSERTE(_CrtIsValidHeapPointer(pUserData))

2013年08月10日 ⁄ 综合 ⁄ 共 1475字 ⁄ 字号 评论关闭

从下面这个例子,得到的剖析结果:

代码分析:设置头域的编号,添加到注册报文中,现在唯一的一点就是需要说明编译的环境和使用出现的问题:

使用2010版本的VS,在程序运行到一定程度的时候崩溃,也就是出现异常

osip_cseq_set_number(reg->cseq,"2");

下面是异常调试的结果:

        /*
         * If this ASSERT fails, a bad pointer has been passed in. It may be
         * totally bogus, or it may have been allocated from another heap.
         * The pointer MUST come from the 'local' heap.
         */
        _ASSERTE(_CrtIsValidHeapPointer(pUserData));

开始解释上面:如果这个断言失败,一个坏指针已经被传递进去(在这里,说出自己的理解:“2”是一个栈区空间的地址,这是一个内存块,当然可以有一个指向这个内存块的指针,现在我们尝试使用free()函数释放一个栈区空间的指针,当然会出现一个问题(系统崩溃),因为这不是一个值得商量的问题(不允许释放栈区的对象,这是真理),它很可能不是真的(bogus确实是一个英文值得斟酌的地方)或者它很可能被其他的堆区分配内存地址,但是很遗憾,它不许来自本地的堆区

总而言之:这不是一个本地的堆区地址,而是一个栈区的地址

但是,很多的时候,程序的崩溃不是一下子就崩溃,而是有预谋和事件的准备,就像是战争,酝酿已久!!

这是一个错误的写法,应该是下面这种情况才是正确的代码编写方式:

//osip_cseq_set_number(reg->cseq,strdup("2"));

申请一个动态内存块,然后,链接到cseq这个结构体中

  typedef struct osip_cseq osip_cseq_t;

 

/**

 * Definition of the CSeq header.

 * @struct osip_cseq

 */

  struct osip_cseq

  {

method是我们无法理解的打次,应该如何去理解这个字段的意义

    char *method;    /**< CSeq method */

    char *number;    /**< CSeq number */

  };

************************************************一些知识储备******************

现在分析如下:
这是一种极端的情况,所以整个程序没有办法进行断点调试
搜集消息如下:
dbgheap.c提示用户的堆栈越界
用于内存分配的管理信息被写坏了,检查有没有越界访问的情况
在使用malloc进行内存分配的时候,系统除了给用户保留的块外还给自己也保留了一些方便于内存管理用。

例如当malloc(5)的时候,给用户分配了5个字节,同时系统也还会记录4个字节(可能还有一些其它的信息)在free的时候使用。具体如下:
当malloc(5)的时候分配的地址如下:
0x003A32E8
cd cd cd cd cd fd fd fd fd xx xx ...
可以看到,前面的5个0xcd就是给用户使用的,而后面的4个0xfd就是系统使用的,
在free的时候会检查(使用函数static int __cdecl CheckBytes(unsigned char * pb,unsigned char bCheck,size_t nSize))这4个字节的内容,
如果有一个字节不为0xfd的话就弹出楼主所说的错误了。

抱歉!评论已关闭.