在链表中插入元素(InsertElement 项目引发异常 class 'External: SIGSEGV' )
Inserting element in a linked list (Project InsertElement raised exception class 'External: SIGSEGV' )
我写了这个程序,它应该从用户输入创建一个整数链表,直到用户插入“0”,打印它,在它的末尾添加一个元素,然后再次打印链表,包括添加的元素。
当我 运行 它时,输入和第一个输出工作正常,但是当涉及到添加新元素时,我收到以下错误消息:
"Project InsertElement raised exception class 'External: SIGSEGV' in
file 'InsertElement.lpr' at line 66: OutRefEnd^.next := RefNew;"
很明显,第66行有问题:
OutRefEnd^.next := RefNew;
但我无法弄清楚那个问题是什么,它是否与我的代码有关,或者它是否只是编译器。据我所知,错误代码暗示 'outRefEnd^.next'` 指向一个空地址,但由于我为其分配了值 'RefNew',我不太明白为什么这应该是第一名.
有人可以提示我哪里出错了吗?
这是我的代码:
program InserElement(input, output);
{Has the user type in integers and forms a linked list out of them,
then inserts an element at the end of that linked list and prints the
linked list with the added new element}
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes;
type
tRefList = ^tList;
tList = record
info : integer;
next : tRefList
end;
var
RefBeginning: tRefList;
RefEnd : tRefList;
Pointer : tRefList;
Number : integer;
procedure CreateList( var outRefBeginning: tRefList);
{ Creates a linear list through user input }
begin
readln(Number);
while Number <> 0 do
begin
new (Pointer);
Pointer^.info := Number;
Pointer^.next := outRefBeginning;
outRefBeginning := Pointer;
readln (Number)
end { while-loop }
end; {CreateList}
procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList);
{ Inserts a new element at the end of the list. outRefBeginning points to the first
element of that list, outRefEnd points to the last element of it. The Value of inNumber is
assigned to the record component info of the new element}
var
RefNew : tRefList;
begin
{ Create and initialise new element }
new(RefNew);
RefNew^.info := inNumber;
RefNew^.next := nil;
{ Insert element at the end of the linear list }
if outRefBeginning = nil then
begin
outRefBeginning := RefNew;
outRefEnd := RefNew
end
else
begin
outRefEnd^.next := RefNew;
outRefEnd := RefNew;
end;
end;{ InsertElement }
procedure PrintList;
{ Prints all elements of the linked list }
var
RefNew : tRefList;
begin
RefNew := RefBeginning;
while RefNew <> nil do
begin
writeln (RefNew^.info);
RefNew := RefNew^.next
end;
end;
begin
RefBeginning := nil;
RefEnd := RefBeginning;
CreateList(RefBeginning);
PrintList;
InsertElement(5,RefBeginning,RefEnd);
PrintList;
readln;
end.
[编辑]
对于任何感兴趣的人,我将在下面粘贴更正后的代码,我根据汤姆的回答中的建议进行了更改。
变化:
我删除了指针变量,因为不再需要它:
var
RefBeginning: tRefList;
RefEnd : tRefList;
Number : integer;
我将 procedure CreateList
更改为类似于 procedure InsertElement
,因为它不仅在 RefBeginning
中而且在 [= 中保存了新元素的值20=]:
procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd: tRefList);
{ Creates a linear list through user input }
var
RefNew : tRefList;`
begin
writeln('Please key in natural numbers. Key in 0 once you are done. ');
readln(Number);
while Number <> 0 do
begin
new (RefNew);
RefNew^.info := Number;
RefNew^.next := nil;
if outRefBeginning = nil then
begin
outRefBeginning := RefNew;
OutRefEnd := RefNew;
end
else
begin
outRefEnd^.next := RefNew;
outRefEnd := RefNew
end;
readln (Number)
end; { while-loop }
end; {CreateList}
最后但同样重要的是,这是完整的代码:
program InserElement(input, output);
{Has the user type in integers and forms a linked list out of them,
then inserts an element at the end of that linked list and prints the
linked list with the added new element}
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes;
type
tRefList = ^tList;
tList = record
info : integer;
next : tRefList
end;
var
RefBeginning: tRefList;
RefEnd : tRefList;
Number : integer;
procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd: tRefList);
{ Creates a linear list through user input }
var
RefNew : tRefList;
begin
writeln('Please key in natural numbers. Key in 0 once you are done. ');
readln(Number);
while Number <> 0 do
begin
new (RefNew);
RefNew^.info := Number;
RefNew^.next := nil;
if outRefBeginning = nil then
begin
outRefBeginning := RefNew;
OutRefEnd := RefNew;
end
else
begin
outRefEnd^.next := RefNew;
outRefEnd := RefNew
end;
readln (Number)
end; { while-loop }
end; {CreateList}
procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList);
{ Inserts a new element at the end of the list. outRefBeginning points to the first
element of that list, outRefEnd points to the last element of it. The Value of inNumber is
assigned to the record component info of the new element}
var
RefNew : tRefList;
begin
{ Create and initialise new element }
new(RefNew);
RefNew^.info := inNumber;
RefNew^.next := nil;
{ Insert element at the end of the linear list }
if outRefBeginning = nil then
begin
outRefBeginning := RefNew;
outRefEnd := RefNew
end
else
begin
outRefEnd^.next := RefNew;
outRefEnd := RefNew;
end;
end;{ InsertElement }
procedure PrintList;
{ Prints all elements of the linked list }
var
RefNew : tRefList;
begin
RefNew := RefBeginning;
while RefNew <> nil do
begin
writeln (RefNew^.info);
RefNew := RefNew^.next
end;
end;
begin
RefBeginning := nil;
RefEnd := nil;
CreateList(RefBeginning, RefEnd);
InsertElement(5,RefBeginning,RefEnd);
PrintList;
readln;
end.
您在 procedure CreateList();
中出错,因为您将新记录添加到开头而不是结尾。 RefEnd
在 CreateList()
之后仍然是 nil
。
当您随后使用 RefEnd = nil
调用 InsertElement(5,RefBeginning,RefEnd);
时,由于参数 outRefEnd
为零,因此在行 outRefEnd^.next := RefNew;
上触发了错误。
您应该更正 CreateList()
程序,使其基本上与 InsertElement
类似,将初始项目链接到 outRefBeginning
和 outRefEnd
并将后续新项目链接到 outRefEnd
.
我写了这个程序,它应该从用户输入创建一个整数链表,直到用户插入“0”,打印它,在它的末尾添加一个元素,然后再次打印链表,包括添加的元素。
当我 运行 它时,输入和第一个输出工作正常,但是当涉及到添加新元素时,我收到以下错误消息:
"Project InsertElement raised exception class 'External: SIGSEGV' in file 'InsertElement.lpr' at line 66: OutRefEnd^.next := RefNew;"
很明显,第66行有问题:
OutRefEnd^.next := RefNew;
但我无法弄清楚那个问题是什么,它是否与我的代码有关,或者它是否只是编译器。据我所知,错误代码暗示 'outRefEnd^.next'` 指向一个空地址,但由于我为其分配了值 'RefNew',我不太明白为什么这应该是第一名.
有人可以提示我哪里出错了吗?
这是我的代码:
program InserElement(input, output);
{Has the user type in integers and forms a linked list out of them,
then inserts an element at the end of that linked list and prints the
linked list with the added new element}
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes;
type
tRefList = ^tList;
tList = record
info : integer;
next : tRefList
end;
var
RefBeginning: tRefList;
RefEnd : tRefList;
Pointer : tRefList;
Number : integer;
procedure CreateList( var outRefBeginning: tRefList);
{ Creates a linear list through user input }
begin
readln(Number);
while Number <> 0 do
begin
new (Pointer);
Pointer^.info := Number;
Pointer^.next := outRefBeginning;
outRefBeginning := Pointer;
readln (Number)
end { while-loop }
end; {CreateList}
procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList);
{ Inserts a new element at the end of the list. outRefBeginning points to the first
element of that list, outRefEnd points to the last element of it. The Value of inNumber is
assigned to the record component info of the new element}
var
RefNew : tRefList;
begin
{ Create and initialise new element }
new(RefNew);
RefNew^.info := inNumber;
RefNew^.next := nil;
{ Insert element at the end of the linear list }
if outRefBeginning = nil then
begin
outRefBeginning := RefNew;
outRefEnd := RefNew
end
else
begin
outRefEnd^.next := RefNew;
outRefEnd := RefNew;
end;
end;{ InsertElement }
procedure PrintList;
{ Prints all elements of the linked list }
var
RefNew : tRefList;
begin
RefNew := RefBeginning;
while RefNew <> nil do
begin
writeln (RefNew^.info);
RefNew := RefNew^.next
end;
end;
begin
RefBeginning := nil;
RefEnd := RefBeginning;
CreateList(RefBeginning);
PrintList;
InsertElement(5,RefBeginning,RefEnd);
PrintList;
readln;
end.
[编辑] 对于任何感兴趣的人,我将在下面粘贴更正后的代码,我根据汤姆的回答中的建议进行了更改。
变化:
我删除了指针变量,因为不再需要它:
var RefBeginning: tRefList; RefEnd : tRefList; Number : integer;
我将
procedure CreateList
更改为类似于procedure InsertElement
,因为它不仅在RefBeginning
中而且在 [= 中保存了新元素的值20=]:procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd: tRefList); { Creates a linear list through user input } var RefNew : tRefList;` begin writeln('Please key in natural numbers. Key in 0 once you are done. '); readln(Number); while Number <> 0 do begin new (RefNew); RefNew^.info := Number; RefNew^.next := nil; if outRefBeginning = nil then begin outRefBeginning := RefNew; OutRefEnd := RefNew; end else begin outRefEnd^.next := RefNew; outRefEnd := RefNew end; readln (Number) end; { while-loop } end; {CreateList}
最后但同样重要的是,这是完整的代码:
program InserElement(input, output); {Has the user type in integers and forms a linked list out of them, then inserts an element at the end of that linked list and prints the linked list with the added new element} {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes; type tRefList = ^tList; tList = record info : integer; next : tRefList end; var RefBeginning: tRefList; RefEnd : tRefList; Number : integer; procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd: tRefList); { Creates a linear list through user input } var RefNew : tRefList; begin writeln('Please key in natural numbers. Key in 0 once you are done. '); readln(Number); while Number <> 0 do begin new (RefNew); RefNew^.info := Number; RefNew^.next := nil; if outRefBeginning = nil then begin outRefBeginning := RefNew; OutRefEnd := RefNew; end else begin outRefEnd^.next := RefNew; outRefEnd := RefNew end; readln (Number) end; { while-loop } end; {CreateList} procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList); { Inserts a new element at the end of the list. outRefBeginning points to the first element of that list, outRefEnd points to the last element of it. The Value of inNumber is assigned to the record component info of the new element} var RefNew : tRefList; begin { Create and initialise new element } new(RefNew); RefNew^.info := inNumber; RefNew^.next := nil; { Insert element at the end of the linear list } if outRefBeginning = nil then begin outRefBeginning := RefNew; outRefEnd := RefNew end else begin outRefEnd^.next := RefNew; outRefEnd := RefNew; end; end;{ InsertElement } procedure PrintList; { Prints all elements of the linked list } var RefNew : tRefList; begin RefNew := RefBeginning; while RefNew <> nil do begin writeln (RefNew^.info); RefNew := RefNew^.next end; end; begin RefBeginning := nil; RefEnd := nil; CreateList(RefBeginning, RefEnd); InsertElement(5,RefBeginning,RefEnd); PrintList; readln; end.
您在 procedure CreateList();
中出错,因为您将新记录添加到开头而不是结尾。 RefEnd
在 CreateList()
之后仍然是 nil
。
当您随后使用 RefEnd = nil
调用 InsertElement(5,RefBeginning,RefEnd);
时,由于参数 outRefEnd
为零,因此在行 outRefEnd^.next := RefNew;
上触发了错误。
您应该更正 CreateList()
程序,使其基本上与 InsertElement
类似,将初始项目链接到 outRefBeginning
和 outRefEnd
并将后续新项目链接到 outRefEnd
.