申請(qǐng)內(nèi)存問(wèn)題
#include?<string.h> #include?<iostream> using?namespace?std; int?main(void) { ????//在堆中申請(qǐng)100個(gè)char類型的內(nèi)存 ????char?*str?=?new?char[6]; ????//拷貝Hello?C++字符串到分配的堆中的內(nèi)存中 ????strcpy(str,?"Hello?imooc"); ????//打印字符串 ????cout?<<?str?<<?endl; ????//釋放內(nèi)存 ????delete?[]str; ????str?=NULL; ????return?0; }
//申請(qǐng)的內(nèi)存小于Hello imooc,為什么也成功。
2016-08-08
學(xué)習(xí)了?。?!牛!
2016-07-27
回答很有用!
2016-06-06
????盡管樓主的代碼可以得到正確輸出,但實(shí)際上發(fā)生了‘緩沖溢出’的錯(cuò)誤。之所以樓主得到正確輸出應(yīng)該是視頻作者提供的編譯器存在Bug沒(méi)有報(bào)錯(cuò)導(dǎo)致的。排名第一的答案在VS2015中編譯也會(huì)報(bào)錯(cuò)。
????錯(cuò)誤的根源在于strcpy函數(shù)。strcmp函數(shù)在運(yùn)行時(shí)的過(guò)程如下:首先生成一個(gè)緩沖區(qū)buffer,緩沖區(qū)沒(méi)有限制大小可以接收任意長(zhǎng)的字符串(本例為"Hello?imooc")。然互緩沖區(qū)中的字符串拷貝到str,str在內(nèi)存中指向char型數(shù)組(大小為6字節(jié)),也就是說(shuō)"Hello?imooc"拷貝到了char型數(shù)組中。盡管數(shù)組大小為6不夠存放"Hello?imooc"字符串,"Hello?imooc"中的超出的部分會(huì)繼續(xù)存在char型數(shù)組之后的內(nèi)存地址中。
????那么當(dāng)執(zhí)行cout?<<?str?<<?endl時(shí),會(huì)完整的輸出"Hello?imooc"字符串。因?yàn)樽址趦?nèi)存中存放時(shí)是以‘\0’結(jié)束,cout函數(shù)輸出str時(shí),遇到‘\0’才會(huì)結(jié)束輸出。而‘\0’并沒(méi)有在大小為6字節(jié)的char數(shù)組(指針str指向數(shù)組起始地址)里面,而是在char數(shù)組之后的內(nèi)存地址中,所以cout讀取完數(shù)組之后并不會(huì)停止,還會(huì)繼續(xù)讀取內(nèi)存中數(shù)組之后的字符串直到遇到‘\0’才結(jié)束輸出。
????另外排名第一的答案在VS2015中編譯也會(huì)報(bào)錯(cuò),也是由于strcmp函數(shù)。因?yàn)閟trcmp函數(shù)執(zhí)行時(shí)產(chǎn)生的緩沖區(qū)buffer沒(méi)有指定大小,很可能發(fā)生‘緩沖溢出’的風(fēng)險(xiǎn)。這其實(shí)是strcmp這個(gè)函數(shù)自身的Bug。解決辦法是換成strcmp函數(shù)改為strcmp_s函數(shù),strcmp_s函數(shù)中的第二個(gè)參數(shù)會(huì)指定緩沖區(qū)buffer的大小,從而避免了‘緩沖溢出’的錯(cuò)誤。
????正確的代碼應(yīng)該如下(VS2015環(huán)境親測(cè)),注意下面加粗傾斜字體:
#include <string.h>
#include <iostream>
using namespace std;
int main(void)
{
//在堆中申請(qǐng)100個(gè)char類型的內(nèi)存
char *str = new char[20];
//拷貝Hello C++字符串到分配的堆中的內(nèi)存中
strcpy_s(str,15, "Hello imooc");
//打印字符串
cout << str << endl;
//釋放內(nèi)存
delete []str;
str = NULL;
system("pause");
return 0;
}
另外附上一片博客供樓主參考:http://blog.csdn.net/wiscada/article/details/3123812。
我是根據(jù)這篇文字才知道的答案。