复制如何为动态变量工作?为什么我们使用一个指针来初始化它们?动态内存拷贝如何工作?
int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;
上面的代码是做什么的?
复制如何为动态变量工作?为什么我们使用一个指针来初始化它们?动态内存拷贝如何工作?
int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;
上面的代码是做什么的?
分析:
线#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 a
后添加delete b
作为步骤2和3的替代方法,您可以简单地将int* b = new int
更改为int* b
。
由线撕裂下来行:
int* a = new int;
上分配的自由存储区的int
变量和a
存储其地址,其类型为pointer to int
。
a = 5;
你可能想要写*a = 5;
代替,这将值5
到int
变量通过a
指向。
int* b = new int;
上分配的自由存储有int
变量和其地址存储在b
其类型为pointer to int
。
b = a;
你可能想要写*b = *a;
来代替,该分配int
变量的值指向b
到int
变量通过a
指向。
b = a;
让b指向了同一个变量int
所指向的a
,你立即失去跟踪int
变量的最初指向b
,这是一个内存泄漏。
delete a;
解除分配int
变量通过a
指向。在这里你也应该delete b;
,否则就是内存泄漏。
我建议你在编写任何实际代码之前,从C/C++指针概念的最开始。
也许你想分配5到一个指向的地址:
*a = 5;
然后你做
b = a;
b为指向一个指向相同的内存: 含5的一个。
当你
delete a;
您释放了a和b指向的内存。
在这一点上,你泄漏了最初由b指出的内存。作为经验法则,每一个新的匹配删除。
但你可能要做到以下几点:
int* a = new int;
*a = 5;
int* b = new int;
*b = *a;
delete a;
delete b;
这意味着你分配的内存*一个 然后分配5 *一, 分配为* B的存储,复制*一对* b 并释放内存。
我们使用指针访问堆上的内存 - 这是当函数返回时不会消失的内存。
您b = a
不会复制存储器中的内容,而不是它叫:
1)创建的第二个堆内存是没有再访问
2)这两个变量a
和b
现在参考到第一行创建的相同内存。
delete a
然后释放该内存。它不应再被使用(a
和b
现在指向你不应该使用的东西)。在第三行中分配的内存永远不会被释放(所以它被“泄漏”)。
你的代码甚至没有编译,因为你的第二行是错误的。这可能与某些编译标志工作寿
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位,所以你会使用更多的内存来传递指针。我不是C++专家,所以如果我看到一个明显的错误,请纠正我。我不想传播任何错误信息。
你在问什么?你想知道为什么你的代码不能编译? – juanchopanza
什么是动态变量?你为什么认为它复制时的行为有所不同? –
你可以看看http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address –