#include <windows.h>
#include <stdio.h>//测试函数
void testFun(char *p, int iLen)
{
 char *hPtr;
 char *header;
 char *hend;
 char c; int iChannel = 0x03;
 char *m_body = (char *)malloc(1024);
 memset(m_body, 0 , 1024);
 memcpy(m_body, p, iLen); //内存拷贝 if (m_body)
 {
  header = m_body - 2;
  hend = m_body;
 }
 else
 {
  return;
 } c |=  iChannel;
 hPtr = header;  /*
  在这里释放不会出错
  if (m_body)
  {
  free(m_body); 
  m_body = NULL;
  }
  */  *hPtr++ = c;
  if (m_body)
  {
   //释放指针,提示越界错误!!!
   free(m_body); 
   m_body = NULL;
  }
}//主函数
int main()
{
 char *p = (char *)malloc(1024);
 memset(p, 0 , 1024);
 memcpy(p, "test", strlen("test")); testFun(p, strlen("test")); //调用函数  if (p)
  {
  free(p);
  p = NULL;
 }
 
 system("pause"); return 0;
}

解决方案 »

  1.   

    *hPtr++ = c;这里越界访问了
      

  2.   

     header = m_body - 2;这里已经把指针指向了一个错误的地方了(越界了);
    经过以下两句;
    hPtr = header;
    *hPtr++ = c;
    实际上是在往一个错误的地方写数据,已经把堆破坏了.
    所以你释放的时候就会崩溃,应该提示堆被破坏吧,不知道为什么会是提示越界,我还没看到C/c++编写的程序崩溃时提示越界的,也许是我没见过吧.
      

  3.   

    *hPtr++ = c;
    这句越界了,hPtr++的地址是m_body - 2,在分配内存区域之前两个字节,当然越界,
      

  4.   

    debug版本会提示越界,堆破坏也是越界的一种表现,vc的debug版本会在分配区之前和之后写入标志,然后检查这些标志是否被错误写入,
      

  5.   

    你修改的不是字符串常量,而是m_body - 2的内存地址,这是在你分配的内存之前两个字节,
      

  6.   

    =====================
    是的, 提示 heap corruption detected 错误......
      

  7.   

    很显然
    代码header = m_body - 2;
    hPtr = header;
    *hPtr++ = c;
    访问了分配内存之前的内存,破坏了堆,
    指针越界是堆破坏的一种
      

  8.   

    =======================
    header = m_body; //正常访问header =  header - 2; //这样属于越界访问么?
      

  9.   

    //这样处理应该没有问题吧?
     char *m_body = (char *)malloc(iLen + 12); //多申请12字节
     memset(m_body, 0 , iLen+ 12); //初始化
     memcpy(m_body + 12, p, iLen); //内存拷贝 if (m_body)
     {
      header = m_body + 12 - 2; //有可能是减12
      hend   = m_body + 12;
     }