s3c2410上移植的全过程详解.htm
来自「2410开发板上的声卡驱动!网上收集!很全的啊!1341型号」· HTM 代码 · 共 568 行 · 第 1/4 页
HTM
568 行
<p><span>{</span></p>
<p><span>char *str = NULL;</span></p>
<p><span>GetMemory(str);<span> </span></span></p>
<p><span>strcpy(str, "hello world");</span></p>
<p><span>printf(str);</span></p>
<p><span>}</span></p>
<p> </p>
<p><span>请问运行<span>Test</span>函数会有什么样的结果?</span></p>
<p><strong><span>答:程序崩溃。</span></strong></p>
<p><strong><span>因为</span><span>GetMemory</span></strong><strong><span>并不能传递动态内存,</span></strong></p>
<p><strong><span>Test</span></strong><strong><span>函数中的<span> str</span>一直都是 <span>NULL</span>。</span></strong></p>
<p><strong><span>strcpy(str, "hello world");</span></strong><strong><span>将使</span></strong><strong><span>程序崩溃。</span></strong></p>
<p> </p>
</td>
<td valign="top" width="291">
<p><span>char *GetMemory(void)</span></p>
<p><span>{<span> </span></span></p>
<p><span>char p[] = "hello world";</span></p>
<p><span>return p;</span></p>
<p><span>}</span></p>
<p><span>void Test(void)</span></p>
<p><span>{</span></p>
<p><span>char *str = NULL;</span></p>
<p><span>str = GetMemory();<span> </span></span></p>
<p><span>printf(str);</span></p>
<p><span>}</span></p>
<p> </p>
<p><span>请问运行<span>Test</span>函数会有什么样的结果?</span></p>
<p><strong><span>答:可能是乱码。</span></strong></p>
<p><strong><span>因为<span>GetMemory</span>返回的是指向“栈内存”的指针,该指针的地址不是<span> NULL</span>,但其原现的内容已经被清除,新内容不可知。</span></strong></p>
</td>
</tr>
<tr>
<td valign="top" width="291">
<p><span>void GetMemory2(char **p, int num)</span></p>
<p><span>{</span></p>
<p><span>*p = (char *)malloc(num);</span></p>
<p><span>}</span></p>
<p><span>void Test(void)</span></p>
<p><span>{</span></p>
<p><span>char *str = NULL;</span></p>
<p><span>GetMemory(&str, 100);</span></p>
<p><span>strcpy(str, "hello");<span> </span></span></p>
<p><span>printf(str);<span> </span></span></p>
<p><span>}</span></p>
<p><span>请问运行<span>Test</span>函数会有什么样的结果?</span></p>
<p><strong><span>答:</span></strong></p>
<p><strong><span>(</span><span>1</span></strong><strong><span>)能够输出</span></strong><strong><span>hello</span></strong></p>
<p><strong><span>(</span><span>2</span></strong><strong><span>)内存泄漏</span></strong></p>
<p> </p>
<p> </p>
</td>
<td valign="top" width="291">
<p><span>void Test(void)</span></p>
<p><span>{</span></p>
<p><span>char *str = (char *) malloc(100);</span></p>
<p><span><span> </span>strcpy(str, </span><span>“</span><span>hello</span><span>”</span><span>);</span></p>
<p><span><span> </span>free(str); <span> </span></span></p>
<p><span><span> </span>if(str != NULL)</span></p>
<p><span><span> </span>{</span></p>
<p><span><span> </span> strcpy(str, </span><span>“</span><span>world</span><span>”</span><span>);<span> </span></span></p>
<p><span>printf(str);</span></p>
<p><span>}</span></p>
<p><span>}</span></p>
<p><span>请问运行<span>Test</span>函数会有什么样的结果?</span></p>
<p><strong><span>答:篡改动态内存区的内容,后果难以预料,非常危险。</span></strong></p>
<p><strong><span>因为<span>free(str);</span>之后,<span>str</span>成为野指针,</span></strong></p>
<p><strong><span>if(str != NULL)</span></strong><strong><span>语句不起作用。</span></strong></p>
<p> </p>
<p> </p>
</td>
</tr>
</tbody>
</table>
</p>
<p> </p>
<p><strong><span>五、编写</span><span>strcpy</span></strong><strong><span>函数(</span><span>10</span></strong><strong><span>分)</span></strong></p>
<p><span>已知</span><span>strcpy</span><span>函数的原型是</span></p>
<p><span><span> </span>char *strcpy(char *strDest, const char *strSrc);</span></p>
<p><span><span> </span></span><span>其中</span><span>strDest</span><span>是目的字符串,</span><span>strSrc</span><span>是源字符串。</span></p>
<p><span>(</span><span>1</span><span>)不调用</span><span>C++/C</span><span>的字符串库函数,请编写函数</span> <span>strcpy</span></p>
<p align="left"><strong><span>char *strcpy(char *strDest, const char *strSrc);</span></strong><strong></strong></p>
<p align="left"><strong><span>{</span></strong></p>
<p align="left"><strong><span><span> </span>assert((</span><span>str</span></strong><strong><span>Dest!=NULL) && (</span><span>strSrc</span></strong><strong><span> !=NULL));<span> </span>// 2</span></strong><strong><span>分</span></strong></p>
<p align="left"><strong><span><span> </span>char *address = </span><span>str</span></strong><strong><span>Dest;<span> </span>// 2</span></strong><strong><span>分</span></strong></p>
<p align="left"><strong><span><span> </span>while( (*</span><span>str</span></strong><strong><span>Dest++ = *</span><span> strSrc</span></strong><strong><span>++) != </span></strong><strong><span>‘</span></strong><strong><span>\0</span></strong><strong><span>’</span></strong><strong><span> )<span> </span>// 2</span></strong><strong><span>分</span></strong></p>
<p align="left"><strong><span><span> </span></span></strong><strong><span><span> </span>return address ;<span> </span>// 2</span></strong><strong><span>分</span></strong></p>
<p align="left"><strong><span>}</span></strong></p>
<p> </p>
<p><span>(</span><span>2</span><span>)</span><span>strcpy</span><span>能把</span><span>strSrc</span><span>的内容复制到</span><span>strDest</span><span>,为什么还要</span><span>char * </span><span>类型的返回值?</span></p>
<p><strong><span>答:为了实现链式表达式。</span><span><span> </span></span></strong><strong><span>// 2</span></strong><strong><span>分</span></strong></p>
<p><strong><span>例如</span><span><span> </span>int length = strlen( strcpy( strDest, “hello world”) );</span></strong></p>
<p> </p>
<p><strong><span>六、编写类</span><span>String</span></strong><strong><span>的构造函数、析构函数和赋值函数(</span><span>25</span></strong><strong><span>分)</span></strong></p>
<p><span>已知类</span><span>String</span><span>的原型为:</span></p>
<p><span><span> </span>class String</span></p>
<p><span><span> </span>{</span></p>
<p><span><span> </span> public:</span></p>
<p><span><span> </span>String(const char *str = NULL);<span> </span>// </span><span>普通构造函数</span></p>
<p><span><span> </span>String(const String &other);<span> </span><span> </span>// </span><span>拷贝构造函数</span></p>
<p><span><span> </span>~ String(void);<span> </span><span> </span><span> </span>// </span><span>析构函数</span></p>
<p><span><span> </span>String & operate =(const String &other);<span> </span>// </span><span>赋值函数</span></p>
<p><span><span> </span> private:</span></p>
<p><span><span> </span>char *m_data;<span> </span><span> </span><span> </span>// </span><span>用于保存字符串</span></p>
<p><span><span> </span>};</span></p>
<p><span><span> </span></span><span>请编写</span><span>String</span><span>的上述<span>4</span>个函数。</span></p>
<p><strong><span>标准答案:</span></strong></p>
<p> </p>
<p><span>// String</span><span>的析构函数</span></p>
<p><strong><span><span> </span>String::</span></strong><strong><span>~String(void)<span> </span>// 3</span></strong><strong><span>分</span></strong></p>
<p><strong><span>{</span></strong></p>
<p><strong><span><span> </span>delete [] m_data;<span> </span><span> </span></span></strong></p>
<p><strong><span>// </span></strong><strong><span>由于<span>m_data</span>是内部数据类型,也可以写成<span> delete m_data;</span></span></strong></p>
<p><strong><span><span> </span>}</span></strong></p>
<p> </p>
<p><span><span> </span></span><span>// String</span><span>的普通构造函数<span><span> </span></span></span></p>
<p><strong><span><span> </span>String::</span></strong><strong><span>String(const char *str)<span> </span>// 6</span></strong><strong><span>分</span></strong></p>
<p><strong><span>{</span></strong></p>
<p><strong><span><span> </span>if(str==NULL)<span> </span></span></strong></p>
<p><strong><span><span> </span>{</span></strong></p>
<p><strong><span><span> </span>m_data = new char[1];<span> </span>// </span></strong><strong><span>若能加 <span>NULL </span>判断则更好</span></strong></p>
<p><strong><span><span> </span>*m_data = </span></strong><strong><span>‘</span></strong><strong><span>\0</span></strong><strong><span>’</span></strong><strong><span>;<span> </span></span></strong></p>
<p><strong><span><span> </span>}<span> </span><span> </span></span></strong></p>
<p><strong><span><span> </span>else</span></strong></p>
<p><strong><span><span> </span>{</span></strong></p>
<p><strong><span><span> </span>int length = strlen(str);<span> </span></span></strong></p>
<p><strong><span><span> </span>m_data = new char[length+1]; // </span></strong><strong><span>若能加 <span>NULL </span>判断则更好<span><span> </span></span></span></strong></p>
<p><strong><span><span> </span>strcpy(m_data, str);<span> </span></span></strong></p>
<p><strong><span><span> </span>}</span></strong></p>
<p><strong><span>}<span> </span></span></strong></p>
<p><span>// </span><span>拷贝构造函数</span></p>
<p><strong><span><span> </span>String::String(const String &other)<span> </span>// 3</span></strong><strong><span>分</span></strong></p>
<p><strong><span><span> </span>{<span> </span></span></strong></p>
<p><strong><span><span> </span>int length = strlen(other.m_data);<span> </span></span></strong></p>
<p><strong><span><span> </span>m_data = new char[length+1];<span> </span>// </span></strong><strong><span>若能加 <span>NULL </span>判断则更好<span><span> </span></span></span></strong></p>
<p><strong><span><span> </span>strcpy(m_data, other.m_data);<span> </span></span></strong></p>
<p><strong><span>}</span></strong></p>
<p><span>// </span><span>赋值函数</span></p>
<p><strong><span><span> </span>String & String::operate =(const String &other)<span> </span>// 13</span></strong><strong><span>分</span></strong></p>
<p><strong><span><span> </span>{<span> </span></span></strong></p>
<p><strong><span><span> </span>// (1) </span></strong><strong><span>检查自赋值<span><span> </span>// 4</span>分</span></strong></p>
<p><strong><span><span> </span>if(this == &other)</span></strong></p>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?