Igo*_*nin 1 delphi pascal freepascal dynamic
所以我试图在 fpc 中实现一个 C 风格的堆栈结构,
主要原则是:每个元素都有一个值和一个指向下一个元素的指针,堆栈本身只包含一个指向它最后一个元素的指针
type stackNode = class
public
val: integer;
next: ^stackNode;
end;
type stack = class
private
top: ^stackNode;
public
constructor Create();
procedure push(v: integer);
procedure clear();
function pop():integer;
function back():integer;
destructor Destroy();
end;
Run Code Online (Sandbox Code Playgroud)
这是我push在 C++ 中的实现方式:
void push(_t _v) {
top = new stackNode<_t>(_v, top);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在 pascal 中实现基本相同的代码时
procedure stack.push(v: integer);
var
temp: ^stackNode;
begin
temp := top;
new(top);
top^.next := temp;
top^.val := v;
end;
Run Code Online (Sandbox Code Playgroud)
new()当我尝试将第二个元素推入堆栈时,它在调用后给我一个分段错误。
有些东西告诉我 pascalnew()并没有真正动态分配内存。
是动态内存分配,即使在帕斯卡可能吗?
stackNode是class,不是record。类是引用类型,所以声明一个类型的变量class实际上就是声明一个指向该类型对象的指针。因此,不要用于向该变量^添加额外的间接层。 为传递给它的指针New()的解除引用类型分配内存,因此通过声明topas ^stackNode,即指向指向stackNode对象的指针的指针,您是在告诉New()仅为stackNode指针分配内存,而不是为实际stackNode对象分配内存。
更重要的是,一个class类型的对象需要通过调用类的构造函数来创建,而不是 using New(),它只会分配原始内存而不调用任何构造函数。相反,class类型的对象需要通过调用它们的析构函数来销毁,而不是Dispose().
试试这个:
type
stackNode = class
public
val: integer;
next: stackNode;
end;
stack = class
private
top: stackNode;
public
constructor Create;
destructor Destroy; override;
procedure push(v: integer);
...
end;
...
constructor stack.Create;
begin
inherited;
...
end;
destructor stack.Destroy;
var
temp, next: stackNode;
begin
temp := top;
while temp <> nil do
begin
next := temp;
temp.Free;
temp := next;
end;
inherited;
end;
procedure stack.push(v: integer);
var
temp: stackNode;
begin
temp := top;
top := stackNode.Create;
top.next := temp;
top.val := v;
end;
Run Code Online (Sandbox Code Playgroud)
话虽如此,我建议添加一个构造函数以stackNode将所需的成员值作为输入,例如:
type
stackNode = class
public
val: integer;
next: stackNode;
constructor Create(AValue: Integer; ANext: stackNode = nil);
end;
...
constructor stackNode.Create(AValue: Integer; ANext: stackNode = nil);
begin
inherited Create;
val := AValue;
next := ANext;
end;
Run Code Online (Sandbox Code Playgroud)
这样,push()可以简化为:
procedure stack.push(v: integer);
begin
top := stackNode.Create(v, top);
end;
Run Code Online (Sandbox Code Playgroud)