⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lc_bcb_43.html

📁 C++Builder教学大全
💻 HTML
字号:
<html>



<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>内存问题 </title>

</head>



<body >

<font FACE="宋体">



<p align="center"><strong><big><big>内存问题</big></big></strong></font></p>



<p align="left"><small><font color="#000000"><span class="unnamed1">一、&quot;delete  

p&quot; 会删去 &quot;p&quot; 指针,还是它指到的资料,&quot;*p&quot; ? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

该指针指到的资料。&quot;delete&quot;  

真正的意思是:「删去指针指到的东西」(delete the thing pointed to by)。同样的英文误用也发生在  

C 语言的「释放」指标所指向的记忆体(&quot;free(p)&quot;真正的意思是:&quot;free_the_stuff_pointed_to_by(p)&quot;  

)。 </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">二、能  

&quot;free()&quot; 掉由 &quot;new&quot; 配置到的、&quot;delete&quot; 掉由  

&quot;malloc()&quot; 配置到的记忆体吗? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;  

不行。在同一个程式里,使用 malloc/free 及 new/delete  

是完全合法、合理、安全的;但 free 掉由 new 配置到的,或 delete  

掉由 malloc 配置到的指标则是不合法、不合理的。 <br> 

&nbsp; </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">三、为什麽该用  

&quot;new&quot; 而不是 malloc() ? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

建构子/解构子、型别安全性、可被覆盖(overridability)。建构子/解构子:和  

&quot;malloc(sizeof(Fred))&quot; 不同,&quot;new Fred()&quot; 还会去呼叫Fred  

的建构子。同理,&quot;delete p&quot; 会去呼叫 &quot;*p&quot; 的解构子。 <br> 

&nbsp;&nbsp;&nbsp; 型别安全性:malloc() 会传回一个不具型别安全的  

&quot;void*&quot;,而 &quot;new Fred()&quot; 则会传回正确型态的指标(一个  

&quot;Fred*&quot;)。 <br> 

&nbsp;&nbsp;&nbsp; 可被覆盖:&quot;new&quot;  

是个可被物件类别覆盖的运算子,而 &quot;malloc&quot;  

不是以「各个类别」作为覆盖的基准。 </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">四、为什麽 C++  

不替 &quot;new&quot; 及 &quot;delete&quot; 搭配个 &quot;realloc()&quot; ? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

避免你产生意外。当 realloc() 要拷贝配置区时,它做的是「逐位元  

bitwise」的拷贝,这会弄坏大 <br> 

部份的 C++ 物件。不过 C++  

的物件应该可以自我拷贝才对:用它们自己的拷贝建构子或设定运算子。  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">五、该怎样配置/释放阵列?  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp; 用  

new[] 和 delete[] : </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

Fred* p = new Fred[100]; <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //... <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete [] p; </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

每当你在 &quot;new&quot; 运算式中用了 &quot;[...]&quot; 的话,你就 *!*必须*!*  

在 &quot;delete&quot; 陈述中使用 &quot;[]&quot;  

。这语法是必要的,因为「指向单一元素的指标」与「指向一个阵列的指标」在语法上并无法区分开来。  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">六、万一我忘了将  

&quot;[]&quot; 用在 &quot;delete&quot; 由 &quot;new Fred[n]&quot;  

配置到的阵列,会发生什麽事? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

灾难。这是程式者的--而不是编译器的--责任,去确保 new[] 与  

delete[]  

的正确配对。若你弄错了,编译器不会产生任何编译期或执行期的错误讯息。堆积(heap)被破坏是最可能的结局,或是更糟的,你的程式会当掉。  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">七、成员函数做  

&quot;delete this&quot; 的动作是合法的(并且是好的)吗? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

只要你小心的话就没事。所谓的「小心」是: <br> 

1) 你得 100% 确定 &quot;this&quot; 是由 &quot;new&quot; 配置来的(而非  

&quot;new[]&quot;,亦非自订的&nbsp;&nbsp; &quot;new&quot;  

版本,一定要是最原始的 &quot;new&quot;)。 <br> 

2) 你得 100% 确定该成员函数是此物件最後一个会去呼叫的。 <br> 

3) 做完自杀的动作 (&quot;delete this;&quot;) 後,你不能再去碰  

&quot;this&quot; 的物件了,包括资料及运作行为在内。 <br> 

4) 做完自杀的动作 (&quot;delete this;&quot;) 後,你不能再去碰  

&quot;this&quot;  

指标了。换句话说,你不能查看它、将它与其他指标或是 NULL  

相比较、印出其值、对它转型、对它做任何事情。 </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

很自然的,这项警告也适用於:当 &quot;this&quot;  

是个指向基底类别的指标,而解构子不是virtual 的场合。 </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">八、该怎麽用 new  

来配置多维阵列? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

有很多方法,端视你对阵列大小的伸缩性之要求而定。极端一点的情形,如果你在编译期就知道所有阵列的维度,你可以静态地配置(就像  

C 一样): </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

class Fred { /*...*/ }; </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

void manipulateArray() <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred matrix[10][20]; </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

//使用 matrix[i][j]... </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

//不须特地去释放该阵列 <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

另一个极端情况,如果你希望该矩阵的每个小块都能不一样大,你可以在自由记忆体里配置之:  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

void manipulateArray(unsigned nrows, unsigned ncols[]) <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //'nrows' 是该阵列之列数。 <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //所以合法的列数为 (0, nrows-1)  

开区间。 <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //'ncols[r]' 则是 'r' 列的行数 ('r'  

值域为 [0..nrows-1])。 <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred** matrix = new Fred*[nrows]; <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (unsigned r = 0; r &lt; nrows;  

++r) <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; matrix[r] = new Fred[  

ncols[r] ]; </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

//使用 matrix[i][j]... </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

//释放就是配置的反动作: <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (r = nrows; r &gt; 0; --r) <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete [] matrix[r-1]; <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete [] matrix; <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">九、怎样确保某类别的物件都是用  

&quot;new&quot; 建立的,而非区域或整体/静态变数? </span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;  

确定该类别的建构子都是 &quot;private:&quot; 的,并定义个  

&quot;friend&quot; 或 &quot;static&quot; 函数,来传回一个指向由  

&quot;new&quot; 建造出来的物件(把建构子设成 &quot;protected:&quot;,如果你想要有衍生类别的话)。  

</span></font></small></p> 

 

<p align="left"><small><font color="#000000"><span class="unnamed1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

class Fred {&nbsp;&nbsp;&nbsp; //只允许 Fred 动态配置出来 <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public: <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static Fred* create()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

{ return new Fred();&nbsp;&nbsp;&nbsp;&nbsp; } <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static Fred* create(int i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

{ return new Fred(i);&nbsp;&nbsp;&nbsp; } <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static Fred* create(const Fred&amp;  

fred) { return new Fred(fred); } <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private: <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred(); <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred(int i); <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred(const Fred&amp; fred); <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; virtual ~Fred(); <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }; </span></font></small></p> 

 

<p align="left"><font color="#000000"><span class="unnamed1"><small>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  

main() <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fred* p = Fred::create(5); <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete p; <br> 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </small><br> 

&nbsp; <br> 

&nbsp; </span></font></p> 

 

<p align="center"></p> 

</body> 

</html> 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -