我知道如果对象被删除则地址被释放,如果写入内容,则使用悬空指针:
delete a;
memmove(a,new A(),sizeof(A));
所以,我尝试通过重复创建对象来重复使用“合法”指针(没有未定义的行为),直到再次分配相同的地址:
#include <stdio.h>
int main(){
int* a=new int;
delete a;
int* b=new int;
while(b!=a){
delete b;
b=new int;
*b=123;
}
printf("%d\n",*a);
return 0;
};
代码b中的应该被分配,直到获得相同的地址,然后* a应该是123,因为它指向b,但是我运行代码几次* a的值仍然是0,为什么会这样?这段代码是未定义的行为吗?或者只是因为以这种方式重用指针是不可能的?
我试图改变删除a;删除b;在while循环中,但它仍然会多次打印0。
答案 0 :(得分:1)
这句话,
while(b!=a)
已经是未定义的行为,因为a
不是有效的指针。然后是更多的UB,还有更多的UB。
答案 1 :(得分:1)
您确定实际执行了分配*b = 123
的代码吗?在进入b==a
循环之前,while
可能很有可能,您只是不指定*b
。试试这样:
#include <stdio.h>
int main(){
int* a=new int;
delete a;
int* b=new int;
while(b!=a){
delete b;
b=new int;
}
*b = 123;
printf("%d\n",*a);
return 0;
}
我不明白为什么代码是非法的,因为你可以从你想要的地方获取指针,就像你可以从stdin
读取它们或从网络获取或随机生成地址,直到它们指向有效地址你可以使用它们。
P.S。我阅读了Cheers and hth. - Alf
回答及其下的评论,并阅读了一些关于“使用无效指针值”的确切含义的解释,它是UB。所以我误以上。好消息是从有效地址使用递增一次指针是合法的,因此写for (iter = begin; iter < end; ++iter) {...}
之类的循环不是UB,即使end
没有指向可以使用的地址。
答案 2 :(得分:0)
不,这不合法。你可以通过重复分配获得一个新的,合法的指针这一事实与免费后,内存页仍然由进程拥有的事实无关。
答案 3 :(得分:0)
此外,还有另外两个问题,由于错别字,我猜:
答案 4 :(得分:0)
我认为您打印def myfunc(grid):
for (i, row) in enumerate(grid):
for (j, el) in enumerate(row):
print('{},{}'.format(i, j))
是因为您双重删除了*a = 0
。但如果你纠正我认为你的程序确实有意义
a
以下是我的理解
#include <stdio.h>
int main(){
int* a=new int;
delete a;
int* b=new int;
while(b!=a){
delete b;
b=new int;
*b=123;
}
printf("%d\n",*a);
return 0;
}
和new
delete
。删除后,a
将是一个悬空指针,它将引用一些内存地址(比如a
)。由于您已经删除了该地址的对象(0xff00
),因此可以将其用于后续分配。int
和new
delete
,直到在b
分配另一个对象(int
)。现在,由于变量0xff00
仍具有相同的地址,因此您将退出循环并在该地址处打印任何内容。这是你想要做的吗?我在那里看不到任何违法行为(使用删除的指针没有任何问题,只有解除引用它是非法的,你不会这样做)