动态内存复制如何工作?

时间:2014-02-08 08:29:25

标签: c++ dynamic

复制如何适用于动态变量?为什么我们使用指针来初始化它们?

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

以上代码的作用是什么?

5 个答案:

答案 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操作返回的地址值。

为了解决上述所有问题,您可以执行以下操作:

  1. a = 5更改为*a = 5

  2. b = a更改为*b = *a

  3. delete b

  4. 之后添加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)变量ab现在都引用了第一行中创建的相同内存。

delete a然后释放那个记忆。它不应再被使用(ab现在指向你不应该使用的东西。第三行中分配的内存永远不会被释放(因此它被'泄露')。

答案 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位。

PS:我不是C ++专家所以,如果我看到一个明显的错误,请纠正我。我不想传播任何错误的信息。