We must accept finite disappointment, but we must never lose infinite hope

动态内存申请小记

上一篇 / 下一篇  2008-05-07 10:47:11

Q,YrK6mbc o^1K$@0先看这样一段简单的代码:

6mE&S(}ZQ0 LUPA开源社区UtNIa^

#include <stdio.h>LUPA开源社区 OL b*~ JU

v5o`ff!fpD1^B0int *pPointer;

N k7J{I$^A/X,P0 LUPA开源社区 q3RU'?9~'w}!f

void SomeFunction()
_ }Gx*S1R@0{LUPA开源社区.Tk'B-? [(]n'C+R;G
    int nNumber;LUPA开源社区;C WOe~/C
    nNumber = 25;  LUPA开源社区&u0t$c wD
  // make pPointer point to nNumber:
rf4u3l'C3jl.X4b0    pPointer = &nNumber;LUPA开源社区*z0v7[!dXO4Hh)}
}LUPA开源社区-H"](];b8p)K'q-G

N4ugiX0void main()LUPA开源社区9L\#@(| Bg ]#_[&hD
{
DFp&W p0    SomeFunction(); // make pPointer point to something
h3LfL-Lv0    printf("let me see see");
3D T x|)Z"p?y `0    // why does this fail?LUPA开源社区S/b+dZ K
    printf("Value of *pPointer: %d\n", *pPointer);
EOz0Lc S2W,IvY0}LUPA开源社区K"Zv(T3^/g

0h%B X @ B|h!H;H0这个程序只是调用了SomeFunction()函数,SomeFunction()中定义了变量nNumber,指针pPointer指向nNumber.正如你所看到的,运行结果并不能得到nNumber的值,原因很简单,nNumber只是SomeFunction中定义的局部变量,SomeFunction运行结束后,nNumber的值也就跟着被释放了。所以指针所指向的是一个已经不属于本程序的变量。那么如何解决这个问题呢?这就是动态内存申请所要完成的任务。

QZ?2S#Q3j0a0 LUPA开源社区;`h/MtuY X

(事实上,这里有一个小小的“trap”,如果我们去掉语句printf("let me see see"),就会发现,输出结果是正确的,即*pPointer 的值是25,这又是为什么呢?难道我们上边的说法是不成立的?实际情形是这样的,当为nNumber分配内存的的时候,操作系统是在栈上为其分配空间的,与此同时,OS在其分配表上添加一个入口,使得nNumber成为该memory的owner。分配表的入口有效地阻止了OS将nNumber的memory分配给其他变量。nNumber的地址可以赋给一个指针,但该memory的拥有者owner并未传递,就是说nNumber依然是该memory的owner。当nNumber超出其作用域的时候,OS内存分配表中的入口将被移除,memory被释放,但该操作并未使指针失效,也并没有自动擦出该memory中的内容。由于指针仍然指在相同的内存地址,所以仍然有可能得到正确的结果,但这只是一个假象(fluke),当memory被重新分配时,其原来的值便不复存在)

K"}f2r m-L,sl6A0
#include <stdio.h>

int *pPointer;

void SomeFunction()
{
    // make pPointer point to a new integer
    pPointer = new int;
    *pPointer = 25;
}

void main()
{
    SomeFunction(); // make pPointer point to something
    printf("Value of *pPointer: %d\n", *pPointer);
}
这一次,在SomeFunction中动态申请一个整型变量,使pPointer指向它,当SomeFunction运行结束时,内存变量保存完整,pPointer仍然指向一个有效的数据,所以我们可以得到希望的nNumber的值。然而另外一个问题产生了,那就是内存泄漏。正因为动态内存申请可以完整的保护数据,但同时它也永远不会自动消失,当我们已经不需要它的时候,其仍然占据着宝贵的内存空间,当所有的内存被用尽的时候,也就会导致系统本亏。所以及时释放动态申请的内存是非常重要的。
#include <stdio.h>

int *pPointer;

void SomeFunction()
{
// make pPointer point to a new integer
    pPointer = new int;
    *pPointer = 25;
}

void main()
{
    SomeFunction(); // make pPointer point to something
    printf("Value of *pPointer: %d\n", *pPointer);

    delete pPointer;
}
虽然只是一行代码的差别,但它是不可或缺的。这里需要注意的是,必须释放一个存在的内存空间,如果试图去释放一个已经被释放过得空间,同样会导致程序的崩溃。
试着来表述这样一些相对比较简单的问题。很多时候当我们不能向别人解释清楚一件事情的时候,或许是我们自己对问题本身不够清楚,或许是表达能力不够好,而这两种情况对我来说都经常会遇到,所以无论从知识上还是从技巧上都有许多有待提高和改进的地方。So,Move forward! Never Stop!

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2009-01-09  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 3871
  • 日志数: 58
  • 图片数: 1
  • 建立时间: 2008-02-28
  • 更新时间: 2008-12-02

RSS订阅

Open Toolbar