我很难理解如何区分悬空指针和内存泄漏。我对最近的作业有一些疑问,这使我感到困惑,读完它后,我仍然感到困惑。我不希望有人替我做家庭作业,我想能够理解为什么是什么,如果那是有道理的。
因此,作业:
给出声明:
int *ptrA, *ptrB;
告诉下面的每个代码段是否导致内存泄漏,悬空指针或两者都不导致。画画来帮助。
ptrA
已经指向内存中的某物,因此该指针既不是悬空指针也不是内存泄漏。ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
ptrB
指向任何东西。ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
ptrA = LocationOfAge();
其中函数LocationOfAge
定义为:
int *LocationOfAge() {
int age = 21;
return &age;
}
感谢任何愿意提供帮助的人。
答案 0 :(得分:10)
游戏规则:
new Type
画一个方框。在框中输入一个问题(您不知道里面有什么)。delete p
,请删除p
所指的框。a = b
(没有星星),从变量a
到方框b
划一条线。*x = y
所指的框中,每y
写x
。*x = *y
,请阅读框y
的内容,然后将副本放入x
结果:
第一个问题:
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
让我们逐行执行此操作:
ptrA =新的int;
// Part 1 has a new so draw a box
*********
* ? *
*********
// Part 2 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB =新整数;
// Part 3 has a new so draw another box
ptrA -------> *********
* ? *
*********
*********
* ? *
*********
// Part 4 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB -------> *********
* ? *
*********
* ptrA = 345;
ptrA -------> *********
* 345 *
*********
ptrB -------> *********
* ? *
*********
ptrB = ptrA;
ptrA -------> *********
| * 345 *
| *********
|
ptrB ---- *********
* ? *
*********
似乎您的盒子漏了。也就是说,有一个没有变量指向的盒子。
答案 1 :(得分:0)
- 我猜这很好,因为ptrA已经指向内存中的某物,所以这既不是悬空的指针也不是内存泄漏。
是的,但是现在ptrB
也指向它,而且您也无法释放ptrB
之前指向的内容。
那是一个泄漏。
- 我猜想这是一个悬空指针,因为345是从内存中释放的,所以ptrB指向空。
正确。
- 最后一行是否意味着该指针指向另一个指针?
不,它为<ptrB
所指向的事物>提供<ptrA
所指向的事物>的值。无需更改所涉及的指针,只需分配int
。
- 像上一个问题一样,我不确定指向指针的含义是什么,或者我什至不知道这将达到什么目的。
第二个new int
被泄漏了,因为曾经指向它的东西(ptrB
)现在指向一个第三个 new int
,而前一个可以不再被释放。
- 我知道这是一个悬空的指针,但是我不知道为什么。是因为指针指向的是函数完成后超出范围的局部变量?
是的
答案 2 :(得分:0)
为防止进行所有作业,您的第一个假设是错误的。
1. ptrA = new int;
2. ptrB = new int;
3. *ptrA = 345;
4. ptrB = ptrA;
在第1行中,ptrA创建一个新的整数(已分配字节),在第2行中,ptrB分配了字节。比3中的,分配在1中的内存已满,可以。 但是,在第4行中,ptrB被地址3覆盖,这意味着无法再访问ptrB的原始地址。因此存在内存泄漏,因为第2行分配给整数PtrB的字节再也无法访问了,因为没有指针指向它。
如果您使用箭头为指针和带有?的框来编写图形,则要容易得多。声明和填充时的特定值。因此看起来像:
1. ptrA -> [ ? ]
2. ptrA -> [ ? ], ptrB -> [ ? ]
3. ptrA -> [ 345 ], ptrB -> [ ? ]
4. ptrA -> [ 345 ] <- ptrB, [ ? ]
如您所见,最后一个框[? ]没有指向它的指针。
答案 3 :(得分:0)
让我们一次回答一个问题。
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
在这里,这是内存泄漏。为什么?因为首先没有delete
。其次,当您进行ptrB = ptrA;
时,实际上没有办法为delete
所指向的对象调用ptrB
。
ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
这是一个悬空指针的示例。一旦在ptrA上调用delete
,由ptrA指向的对象将被释放。因此,ptrB指向行为未定义的已释放位置。因此,悬空指针!
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
在这里,仅因为我们没有调用delete
,所以存在内存泄漏。我们正在做的是创建两个分别由ptrA和ptrB指向的对象,两个对象的值均为345。它们仍然在堆中保留空间。但是,为什么两者都具有345的价值?很简单。
完成*ptrA = 345;
时,这意味着ptrA指向的对象的值应设置为345。
当您执行*ptrB = *ptrA;
时,这意味着应该将ptrB指向的对象的值分配给ptrA指向的对象的值。
这是解引用运算符的简单功能。
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
这类似于第一个。在第2行中,ptrB指向动态分配的对象。在执行第4行之后,ptrB指向全新的对象。因此,无法取消分配其内存已在第2行分配的对象的方法。因此,内存泄漏!
int *LocationOfAge() {
int age = 21;
return &age;
}
在这里,age
是一个局部变量,一旦函数结束,它将终止。因此,任何指向该局部变量的指针都会导致未定义的行为。所以,悬空指针!