0x00007FF7A57F2145 处有未经处理的异常(在 洼地提取.exe 中): 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
报错的地方
//如果被搜索过或者不是洼地则跳过
if (searched[row][col]==1 || pit[row][col] <= 0){
return;
}
故障发生在访问动态申请的二维数据,相关代码如下:
// 初始化洼地搜索标记数组
int** initialize_searched(int row_count, int col_count) {
// 动态分配二维数组
int i, j;
int** searched = (int**)malloc(row_count * sizeof(int*));
for (i = 0; i < row_count; i++) {
searched[i] = (int*)malloc(col_count * sizeof(int));
}
// 初始化标记数组searched
for (i = 0; i < row_count; i++) {
for (j = 0; j < col_count; j++) {
searched[i][j] = 0;
}
}
return searched;
}
//初始化洼地数组
int** initialize_pit(int row_count, int col_count) {
int i,j;
int** pit = (int** )malloc(row_count * sizeof(int*));
if (pit == NULL) printf("内存分配失败");
for (i = 0; i < row_count; i++) {
pit[i] = (int*)malloc(col_count * sizeof(int));
if (pit[i] == NULL) printf("内存分配失败");
}
// 初始化洼地为0,正值是洼地
for (i = 0; i < row_count; i++) {
for (j = 0; j < col_count; j++) {
pit[i][j] = 0;
}
}
return pit;
}
for (row = 0; row < row_count; row++) {
for ( col = 0; col < col_count; col++) {
if (searched[row][col]==0 && pit[row][col] > 0) {
printf("%d %d", searched[row][col], pit[row][col]);
PitNode* newPit = (PitNode*)malloc(sizeof(PitNode));
newPit->next = NULL;
newPit->area = 0;
newPit->maxDepth = 0;
newPit->volume = 0;
calculatePit(row, col, searched, Spill, &newPit);
PitNode* p;
p = pitList->next;
pitList->next = newPit;
newPit->next = p;
totalArea += newPit->area;
totalVolume += newPit->volume;
totalNum++;
}
}
}
你这个要叫二叉树,不是二维数组:你内存访问错误就是因为二叉树你当成二维数组访问才出现内存访问错误的!
```c++
int** searched = (int**)malloc(row_count * sizeof(int*));
for (i = 0; i < row_count; i++) {
searched[i] = (int*)malloc(col_count * sizeof(int));
}
//你的二叉树应该这样访问:
if (((int*)(searched[row]))[col]==1 || ((int*)(pit[row]))[col] <= 0){
return;
}
用C语言实现二维数组,没有必要那么麻烦!
```c++
// 初始化洼地搜索标记数组
int** initialize_searched(int row_count, int col_count)
{
// 动态分配二维数组
int i, j;
int** searched = (int**)malloc(col_count * row_count * sizeof(int*));
if(NULL==searched)//if... 要习惯把常量放前面,如果这时候粗心写成:if(NULL=searched) 编译器会直接提示!如果写成 if(searched=NULL) ,编译器是直接赋值再判断,整个逻辑就改变了,而且还不会提示错误!
{
printf(" initialize_searched 函数内存分配失败");
return NULL;
}
// 初始化标记数组searched
for (i = 0; i < row_count; i++)
for (j = 0; j < col_count; j++)
searched[i][j] = 0;
return searched;
}
//initialize_pit 函数也是类似 ,一个磨子刻出来的 没有必要重复写 , 换个参数调用 initialize_searched 就好了!像这样:
int row_count = 10 , col_count = 10 ;
int** searched = initialize_searched( row_count , col_count );
int** pit = initialize_searched( row_count , col_count );
至于内存访问错误,那是可能
1.内存申请太大,没有申请成功就访问!
2.可能你的数组下标访问越界了,没有控制好你的数组下标值
3.在多线程里,可能前面线程已经把该内存释放了,其他线程还在访问!
正好我有个C++类简单内存管理很实用:
```c++
//MemBuffer.h 文件
#pragma once
//#include "MemBuffer.h"
//一个类维持一个内存管理
#define MyGlobalAlloc( o , t , e ) {o = (t)::GlobalAlloc( GPTR ,(e)); memset(o,0,e); }
#define MyGlobalAlloc1( o , t ) {o = (t * )::GlobalAlloc( GPTR ,sizeof(t)); memset(o,0,sizeof(t)); }
#define MyGlobalFree( o ) {if(o){::GlobalFree(o);o=NULL;}}
class CMemBuffer
{
private:
PUCHAR m_Buffer ;
ULONG m_Len ;
public:
CMemBuffer(void);
~CMemBuffer(void);
CMemBuffer(ULONG Len );
public:
PUCHAR GetBuffer(){return m_Buffer;}
ULONG GetLen(){return m_Len ; }
PUCHAR GetBufferMove(){PUCHAR o = m_Buffer; m_Buffer=NULL,m_Len=0;return o;}//移除类内存管理,到自定义释放
PUCHAR ExBuffer(ULONG Len = 1024);//扩展到需要的大小
};
//MemBuffer.cpp 文件
#include "StdAfx.h"
#include "MemBuffer.h"
CMemBuffer::CMemBuffer(void)
{
m_Buffer = NULL;
m_Len = 0 ;
}
CMemBuffer::~CMemBuffer(void)
{
MyGlobalFree( m_Buffer );
}
CMemBuffer::CMemBuffer( ULONG Len )
{
m_Buffer = NULL;
m_Len = 0 ;
if( Len < 1024*1024*1024 )
{
m_Buffer = (PUCHAR)::GlobalAlloc( GPTR , Len );
memset( m_Buffer ,0,Len);
m_Len = Len ;
}
}
PUCHAR CMemBuffer::ExBuffer(ULONG Len)
{
if(( Len > m_Len )||(!m_Buffer))
{
MyGlobalFree( m_Buffer );
m_Len = 0 ;
CMemBuffer c( Len );
m_Len = c.m_Len ;
m_Buffer = c.GetBufferMove();
}
return m_Buffer ;
}
```
在 函数中 临时内存只要内存指针没有从类移除,就不需要自己去释放,函数结束,类自动释放,无需烦恼内存释放泄露!
下面的代码中也没有你说的报错行代码啊