2014-02-08 51 views
2

复制如何为动态变量工作?为什么我们使用一个指针来初始化它们?动态内存拷贝如何工作?

int* a = new int; 
a = 5; 
int* b = new int; 
b = a; 
delete a; 

上面的代码是做什么的?

+1

你在问什么?你想知道为什么你的代码不能编译? – juanchopanza

+0

什么是动态变量?你为什么认为它复制时的行为有所不同? –

+0

你可以看看http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address –

回答

3

分析:

线#1int* a = new int;

变量a被设置为指向一块动态分配的存储器(典型地在堆)的。

2号线a = 5;

可变a设置为指向,以解决5在内存中,所以你已经“丢失”的指针指向一块内存以前分配,你将无法稍后释放它(又称内存泄漏)。

线#3int* b = new int;

b变量被设置为指向一块动态分配的存储器(典型地在堆)的。

线路#4b = a;

b变量被设置以指向可变a指向,即,在存储器地址5。所以再一次,你已经“丢失”了指向先前分配的那块内存的指针,并且以后你将无法释放它。

5号线delete a;

尝试释放以前分配的内存块,位于地址5.这个尝试很可能会导致程序崩溃,因为一个内存访问冲突,如delete操作保证只对先前调用相同类型的new操作返回的地址值成功完成。

为了解决上述所有问题,你可以做到以下几点:

  1. 变化a = 5*a = 5

  2. 变化b = a*b = *a

  3. delete a后添加delete b

作为步骤2和3的替代方法,您可以简单地将int* b = new int更改为int* b

1

由线撕裂下来行:

int* a = new int; 

上分配的自由存储区的int变量和a存储其地址,其类型为pointer to int

a = 5; 

你可能想要写*a = 5;代替,这将值5int变量通过a指向。

int* b = new int; 

上分配的自由存储有int变量和其地址存储在b其类型为pointer to int

b = a; 

你可能想要写*b = *a;来代替,该分配int变量的值指向bint变量通过a指向。
b = a;让b指向了同一个变量int所指向的a,你立即失去跟踪int变量的最初指向b,这是一个内存泄漏。

delete a; 

解除分配int变量通过a指向。在这里你也应该delete b;,否则就是内存泄漏。

我建议你在编写任何实际代码之前,从C/C++指针概念的最开始。

1

也许你想分配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 并释放内存。

1

我们使用指针访问堆上的内存 - 这是当函数返回时不会消失的内存。

b = a不会复制存储器中的内容,而不是它叫:

1)创建的第二个堆内存是没有再访问

2)这两个变量ab现在参考到第一行创建的相同内存。

delete a然后释放该内存。它不应再被使用(ab现在指向你不应该使用的东西)。在第三行中分配的内存永远不会被释放(所以它被“泄漏”)。

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位,所以你会使用更多的内存来传递指针。我不是C++专家,所以如果我看到一个明显的错误,请纠正我。我不想传播任何错误信息。