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

📄 20000916022.htm

📁 C++ Builder学习中文版,让学者对其有一定的理解.
💻 HTM
字号:
<HTML>

<HEAD>

 

<TITLE>关于指针和内存的几个问题</TITLE>



<META content="MSHTML 5.00.2314.1000" name=GENERATOR>

</HEAD>

<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0 

vLink=#990099>



<div align="center">

  <table width="744" border="0" cellspacing="0" cellpadding="0" height="76">

    <tr> 

      <td>

        <p align="center"><font size="3"><br>

          <b>关于指针和内存的几个问题</b></font></p>

        <div align="left"> 

          <p><font color=#663366>一、"delete p" 会删去 "p" 指针,还是它指到的资料,"*p" ?</font> 

          <p>&nbsp;&nbsp;&nbsp; 该指针指到的资料。"delete" 真正的意思是:「删去指针指到的东西」(delete the 

            thing pointed to by)。同样的英文误用也发生在 C 语言的「释放」指标所指向的记忆体("free(p)"真正的意思是:"free_the_stuff_pointed_to_by(p)" 

            )。 

          <p><font color=#663366>二、能 "free()" 掉由 "new" 配置到的、"delete" 掉由 "malloc()" 

            配置到的记忆体吗?</font> 

          <p>&nbsp;&nbsp; 不行。在同一个程式里,使用 malloc/free 及 new/delete 是完全合法、合理、安全的;但 

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

            &nbsp; 

          <p><font color=#000099>三、为什麽该用 "new" 而不是 malloc() ?</font> 

          <p>&nbsp;&nbsp;&nbsp; 建构子/解构子、型别安全性、可被覆盖(overridability)。建构子/解构子:和 "malloc(sizeof(Fred))" 

            不同,"new Fred()" 还会去呼叫Fred 的建构子。同理,"delete p" 会去呼叫 "*p" 的解构子。 <br>

            &nbsp;&nbsp;&nbsp; 型别安全性:malloc() 会传回一个不具型别安全的 "void*",而 "new Fred()" 

            则会传回正确型态的指标(一个 "Fred*")。 <br>

            &nbsp;&nbsp;&nbsp; 可被覆盖:"new" 是个可被物件类别覆盖的运算子,而 "malloc" 不是以「各个类别」作为覆盖的基准。 

          <p><font color=#006600>四、为什麽 C++ 不替 "new" 及 "delete" 搭配个 "realloc()" 

            ?</font> 

          <p>&nbsp;&nbsp;&nbsp; 避免你产生意外。当 realloc() 要拷贝配置区时,它做的是「逐位元 bitwise」的拷贝,这会弄坏大 

            <br>

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

          <p><font color=#666600>五、该怎样配置/释放阵列?</font> 

          <p>&nbsp;&nbsp;&nbsp; 用 new[] 和 delete[] : 

          <p>&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; 

          <p>&nbsp;&nbsp;&nbsp; 每当你在 "new" 运算式中用了 "[...]" 的话,你就 *!*必须*!* 在 "delete" 

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

          <p><font color=#009900>六、万一我忘了将 "[]" 用在 "delete" 由 "new Fred[n]" 配置到的阵列,会发生什麽事?</font> 

          <p>&nbsp;&nbsp;&nbsp; 灾难。这是程式者的--而不是编译器的--责任,去确保 new[] 与 delete[] 的正确配对。若你弄错了,编译器不会产生任何编译期或执行期的错误讯息。堆积(heap)被破坏是最可能的结局,或是更糟的,你的程式会当掉。 

          <p><font color=#cc0000>七、成员函数做 "delete this" 的动作是合法的(并且是好的)吗?</font> 

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

            1) 你得 100% 确定 "this" 是由 "new" 配置来的(而非 "new[]",亦非自订的&nbsp;&nbsp; "new" 

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

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

            3) 做完自杀的动作 ("delete this;") 後,你不能再去碰 "this" 的物件了,包括资料及运作行为在内。 <br>

            4) 做完自杀的动作 ("delete this;") 後,你不能再去碰 "this" 指标了。换句话说,你不能查看它、将它与其他指标或是 

            NULL 相比较、印出其值、对它转型、对它做任何事情。 

          <p>&nbsp;&nbsp;&nbsp; 很自然的,这项警告也适用於:当 "this" 是个指向基底类别的指标,而解构子不是virtual 

            的场合。 

          <p><font color=#ff6600>八、该怎麽用 new 来配置多维阵列?</font> 

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

            C 一样): 

          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Fred { /*...*/ }; 

          <p>&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]; 

          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //使用 matrix[i][j]... 

          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //不须特地去释放该阵列 

            <br>

            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } 

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

          <p>&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] ]; 

          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //使用 matrix[i][j]... 

          <p>&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; } 

          <p><font color=#ff6600>九、怎样确保某类别的物件都是用 "new" 建立的,而非区域或整体/静态变数?</font> 

          <p>&nbsp;&nbsp;&nbsp; 确定该类别的建构子都是 "private:" 的,并定义个 "friend" 或 "static" 

            函数,来传回一个指向由 "new" 建造出来的物件(把建构子设成 "protected:",如果你想要有衍生类别的话)。 

          <p>&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; }; 

          <p>&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; } </p>

        </div>

            </td>

    </tr>

  </table>

 

</div>

</BODY></HTML>

⌨️ 快捷键说明

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