复制如何适用于动态变量?为什么我们使用指针来初始化它们?
int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;
以上代码的作用是什么?
答案 0 :(得分:3)
<强>分析:强>
第1行:int* a = new int;
变量a
设置为指向一块动态分配的内存(通常在堆中)。
第2行:a = 5;
变量a
被设置为指向内存中的地址5,因此您“丢失”了指向先前分配的那段内存的指针,并且您将无法在以后释放它(也就是内存泄漏) )。
第3行:int* b = new int;
变量b
设置为指向一块动态分配的内存(通常在堆中)。
第4行:b = a;
变量b
设置为指向变量a
指向的位置,即内存中的地址5。所以再一次,你“丢失”了之前分配的那段内存的指针,你将无法在以后发布它。
第5行:delete a;
尝试释放位于地址5的先前分配的内存。由于内存访问冲突,此尝试很可能导致程序崩溃,因为delete
操作可确保成功完成仅适用于先前调用相同类型的new
操作返回的地址值。
为了解决上述所有问题,您可以执行以下操作:
将a = 5
更改为*a = 5
将b = a
更改为*b = *a
在delete b
delete a
醇>
作为步骤2和3的替代方法,您只需将int* b = new int
更改为int* b
。
答案 1 :(得分:1)
逐行撕下:
int* a = new int;
在免费商店中分配int
变量,并将其地址存储在类型为a
的{{1}}中。
pointer to int
您可能希望改为编写a = 5;
,将值*a = 5;
分配给5
指向的int
变量。
a
在免费商店中分配int* b = new int;
变量,并将其地址存储在类型为int
的{{1}}中。
b
您可能希望改为编写pointer to int
,它将b = a;
指向的*b = *a;
变量的值分配给int
指向的b
变量}。
int
使b指向a
指向的同一b = a;
变量,您会立即忘记int
最初指向的a
变量,并且内存泄漏。
int
取消分配b
指向的delete a;
变量。在这里你也应该int
,否则就是内存泄漏。
我建议你在编写任何实用代码之前从C / C ++中指针概念的一开始就开始。
答案 2 :(得分:1)
可能你想为a指定的地址分配5:
*a = 5;
然后当你做
b = a;
b指向由a指向的相同内存: 包含5的那个。
当你
delete a;
释放a和b指向的内存。
此时你泄漏了b最初指向的记忆。
根据经验,每个新的匹配都要删除。
但您可能想要执行以下操作:
int* a = new int;
*a = 5;
int* b = new int;
*b = *a;
delete a;
delete b;
意味着您为* a分配内存 然后将5分配给* a, 为* b分配内存,在* b上复制* a 并释放记忆。
答案 3 :(得分:1)
我们使用指针访问堆上的内存 - 这是在函数返回时不会消失的内存。
您的b = a
不会复制该内存的内容,而是会:
1)您创建的第二个堆内存不再可用
2)变量a
和b
现在都引用了第一行中创建的相同内存。
delete a
然后释放那个记忆。它不应再被使用(a
和b
现在指向你不应该使用的东西。第三行中分配的内存永远不会被释放(因此它被'泄露')。
答案 4 :(得分:1)
您的代码甚至无法编译,因为您的第二行是错误的。它可能适用于某些编译器标志
error: invalid conversion from 'int' to 'int*'
你可能想要的是:
int* a = new int;
*a = 5;
int* b = new int;
b = a;
delete a;
以这种方式思考指针:
Variable name | Memory address | Value
1.st line
a | 1000 | 2000 //pointer a at address 1000 points to address 2000 on heap
/ | 2000 | / //int on address 2000 with undefined value
2nd line
/ | 2000 | 5 //set the value at the memory pointed by a to 5
3rd line
b | 1004 | 2500 //another pointer pointing to another int on heap
/ | 2500 | /
4th line
b | 1004 | 2000 //b now points to the address that a is pointing to
5th line
Deallocates memory at address 2000
在第4行,你只是因为丢失了指向第二个int的指针而导致内存泄漏。
为什么要使用指针?因为当您将变量传递给函数时,它们的值被复制,这可能是一项昂贵的操作。例如:
void func(HugeObject ho) {
//do something
}
main() {
HugeObject ho();
func(ho);
}
整个HugeObject将被复制到该函数中。由于这是一个很大的内存,它的运行成本很高。有了指针,这不是问题:
void func(HugeObject * ho) {
//do something
}
main() {
HugeObject * ho = new HugeObject();
func(ho);
delete ho;
}
如果我们使用指针,我们只复制32或64位地址而不是整个对象。
一般来说,在你的代码周围传递int
是一个坏主意,因为你得到指针的所有问题而没有任何好处。事实上,在64位机器上,你会使用更多的内存来传递指针而不是传递整数,因为int通常是32位。