//这是我自定义的类型和指针
type
TFlags = record
bVisited : Boolean;
bMarked : Boolean;
bEdged : Boolean;
bCenter : Boolean;
nColor : Byte;
nDummy : Byte;
end;
PFlags = ^TFlags;
//这是全局的数组
var
arrFlags : array of TFlags;
//我的数组已经用分配内存了
SetLength(arrFlags,sizeof(TFlags) * nWidth * nHeight);
//我定义了一个函数
procedure CountSeeds();
var
x,y : integer;
nCurArea : integer;
cur : PFlags;
begin
nCurArea := 0;
nCellCount := 0;
nCellTotArea := 0;
cur := @arrFlags;
//clear visited
ClearVisited();
//
for y := 0 to nHeight - 1 do
for x := 0 to nWidth - 1 do
begin
Inc(cur);
if cur.bMarked and not cur.bVisited then
begin
ProcessCountSeeds(x,y,cur); //调用这个函数时出现了问题
if (nCellTotArea - nCurArea < MAX_HOLE) and (nCellTotArea - nCurArea > MIN_HOLE) then
nCellCount := nCellCount + 1;
nCurArea := nCellTotArea;
end;
end;
end;
//出现问题的函数是这样定义的
procedure ProcessCountSeeds(nx,ny : integer;cur_flag : PFlags);
var
next : PFlags;
begin
if (nx < 0) or (nx > nWidth - 1) or (ny < 0) or (ny > nHeight - 1) then exit;
//继续
Inc(nCellTotArea);
cur_flag^.bVisited := True; //这个地方出现错误提示(access violation)
//top
if (ny > 0) then
begin
next := Pointer(LongWord(cur_flag) - SizeOf(TFlags) * nWidth);
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx,ny - 1,next);
end;
//bottom
if (ny < nHeight - 1) then
begin
next := Pointer(LongWord(cur_flag) + SizeOf(TFlags) * nWidth);
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx,ny + 1,next);
end;
//left
if nx > 0 then
begin
next := Pointer(LongWord(cur_flag) - SizeOf(TFlags));
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx - 1,ny,next);
end;
//right
if nx < nWidth - 1 then
begin
next := Pointer(LongWord(cur_flag) + SizeOf(TFlags));
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx + 1,ny,next);
end;
end;
//
应该是指针的使用出现的问题,我很少在delphi中使用指针,这里使用也是迫不得已。如果我不使用,直接用nx,ny来确定数组的位置arrFlags[nx + ny * nWidth]则会出现stack overflow的错误提示。还请大家帮忙,我的问题是:
1、上面指针的使用,哪里出现的问题?
2、为什么我直接用nx,ny来确定数组的位置arrFlags[nx + ny * nWidth]会出现上面说的错误?
3、你们也都看到我指针的移动很麻烦(next := Pointer(LongWord(cur_flag) - SizeOf(TFlags) * nWidth)),更简便的方法是什么?
type
TFlags = record
bVisited : Boolean;
bMarked : Boolean;
bEdged : Boolean;
bCenter : Boolean;
nColor : Byte;
nDummy : Byte;
end;
PFlags = ^TFlags;
//这是全局的数组
var
arrFlags : array of TFlags;
//我的数组已经用分配内存了
SetLength(arrFlags,sizeof(TFlags) * nWidth * nHeight);
//我定义了一个函数
procedure CountSeeds();
var
x,y : integer;
nCurArea : integer;
cur : PFlags;
begin
nCurArea := 0;
nCellCount := 0;
nCellTotArea := 0;
cur := @arrFlags;
//clear visited
ClearVisited();
//
for y := 0 to nHeight - 1 do
for x := 0 to nWidth - 1 do
begin
Inc(cur);
if cur.bMarked and not cur.bVisited then
begin
ProcessCountSeeds(x,y,cur); //调用这个函数时出现了问题
if (nCellTotArea - nCurArea < MAX_HOLE) and (nCellTotArea - nCurArea > MIN_HOLE) then
nCellCount := nCellCount + 1;
nCurArea := nCellTotArea;
end;
end;
end;
//出现问题的函数是这样定义的
procedure ProcessCountSeeds(nx,ny : integer;cur_flag : PFlags);
var
next : PFlags;
begin
if (nx < 0) or (nx > nWidth - 1) or (ny < 0) or (ny > nHeight - 1) then exit;
//继续
Inc(nCellTotArea);
cur_flag^.bVisited := True; //这个地方出现错误提示(access violation)
//top
if (ny > 0) then
begin
next := Pointer(LongWord(cur_flag) - SizeOf(TFlags) * nWidth);
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx,ny - 1,next);
end;
//bottom
if (ny < nHeight - 1) then
begin
next := Pointer(LongWord(cur_flag) + SizeOf(TFlags) * nWidth);
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx,ny + 1,next);
end;
//left
if nx > 0 then
begin
next := Pointer(LongWord(cur_flag) - SizeOf(TFlags));
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx - 1,ny,next);
end;
//right
if nx < nWidth - 1 then
begin
next := Pointer(LongWord(cur_flag) + SizeOf(TFlags));
if next^.bMarked and not next^.bVisited then
ProcessCountSeeds(nx + 1,ny,next);
end;
end;
//
应该是指针的使用出现的问题,我很少在delphi中使用指针,这里使用也是迫不得已。如果我不使用,直接用nx,ny来确定数组的位置arrFlags[nx + ny * nWidth]则会出现stack overflow的错误提示。还请大家帮忙,我的问题是:
1、上面指针的使用,哪里出现的问题?
2、为什么我直接用nx,ny来确定数组的位置arrFlags[nx + ny * nWidth]会出现上面说的错误?
3、你们也都看到我指针的移动很麻烦(next := Pointer(LongWord(cur_flag) - SizeOf(TFlags) * nWidth)),更简便的方法是什么?
SetLength设置大小,不是分配具体的byte值,而是根据类型来确定分配内存的,所以用:
SetLength(arrFlags,nWidth * nHeight);直接移动指针的方法为 inc(cur,nwidth)