procedure TForm1.btn1Click(Sender: TObject);
var ptr, ptr2 : ^integer;
i : integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := ptr; //保留原始指针位置
for i := 0 to 19 do
begin
ptr^ := i;
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
FreeMem(ptr2); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,
for i:=1 to 20 do //如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
begin
ShowMessage(IntToStr(ptr^));
Inc (ptr) ;
end
end;
还有我想把赋值的这些数值一个个的showmessage出来,可是我这样写,根本读不出来,不知道是哪边错了,麻烦各位指点一下,呵呵,比较菜的问题啊
因为ptr的位置已发生改变,所以不能以ptr来释放
//如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
这个很多人问过,是对内存释放过程有误解
内存释放只是将该块内存标记为可用,不等于内存清空,在没有被别人使用前,它的内容是不变的
ptr: pinteger;
I, Ptr2 : Integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := Integer(ptr); //保留原始指针位置
for i := 0 to 19 do
begin
ptr^ := i;
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
ptr := PInteger(Ptr2);
FreeMem(ptr); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,
for i:=1 to 20 do //如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
begin
ShowMessage(IntToStr(ptr^));
Inc (ptr) ;
end
end;
// FreeMem(ptr2); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
FreeMem(ptr-20);//把指针移到最初始的位置(FreeMem就是以当前指针为基准,释放内存单元长度为N的函数,很明显,你的当前指针不是最初始的位置,而是进行inc(ptr,20)后的位置,故非法访问是正常的)
FreeMem(ptr);
FreeMem(ptr); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,//此处笔误了 ptr已经指向原来的位置了,后面又Dec
这个问题很有意思,试验了很多次,作了很多变化,都还是有不太明白的地方
var ptr, ptr2 : ^integer;
i : integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := ptr; //保留原始指针位置
for i := 0 to 19 do
begin
ptr^ := i;
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
//FreeMem(ptr2); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,
FreeMem(ptr2, sizeof(integer) * 20); //这一句和上一句作了变化
for i:=1 to 20 do //如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
begin
ShowMessage(IntToStr(ptr^)); //这个地方的结果就奇怪了,前两个地址里面的内容
Inc(ptr); //有错误,但是后面的18个地址中内容却与原来的相同
end
end;
ptr := PInteger(Ptr2); 和 Dec(ptr,20); 后边就可以不要了
最开始两个地址空间中内容错误,后面18的地址空间中内容与原来的(循环中赋值)相同
上边的定义, ptr: pinteger;
所以才能:pstr:=Pinteger(pstr2);
其实要实现你的结果,可以这样:var
ptr, ptr2 : ^integer;
i : integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := ptr; //保留原始指针位置
for i := 0 to 19 do
begin
ptr^ := i;
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
//FreeMem(ptr2); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
//Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,
ptr := ptr2; //这样写的话就可以不用到Dec
for i:=1 to 20 do //如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
begin
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
Dec(ptr, 20); //当然可以作上面一样的变化
FreeMem(ptr, sizeof(integer) * 20); //最后来释放申请的内存空间
end;
这个FreeMem现在搞得我头晕了
FreeMem(ptr, sizeof(integer) * 20); //最后来释放申请的内存空间上面两行,FreeMem(ptr2, sizeof(integer) * 20); 也可以了,这个地方明白了,呵呵
var
ptr: pinteger;
I, Ptr2 : Integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := Integer(ptr); //保留原始指针位置
for i := 0 to 19 do
begin
ptr^ := i;
ShowMessage(IntToStr(ptr^));
Inc(ptr);
end;
ptr := PInteger(Ptr2);
FreeMem(ptr,sizeof(integer) * 20); //为什么这里释放的是ptr2,我试验了如果是ptr就会报地址引用错误,
// Dec(ptr,20); //但是上面的代码如 ptr2 := ptr,如果这样赋值,相当于就引用指针地址了,
for i:=1 to 20 do //如果ptr2释放了,PTR也应该释放啊,为什么没有释放呢?
begin
ShowMessage(IntToStr(ptr^));
Inc (ptr) ;
end
end;这样写为什么会出错呢,我看上去没什么问题啊
ptr,ptr2本身就是2个变量,类似于
var x,y:integer;
Ptr2:=ptr也当于
x:=y;
这个与指针没有关系,无论ptr怎样变化,都不会改变Ptr2的值的