void ? dialog5::OnRclickList1(NMHDR* ? pNMHDR, ? LRESULT* ? pResult) ? ?
? { ?
? // ? TODO: ? Add ? your ? control ? notification ? handler ? code ? here ?
? CMenu ? menu1,*menu2; ?
? CPoint ? point1; ?
? menu1.LoadMenu(IDR_MENU1); ?
? menu2=menu1.GetSubMenu(0); ?
? ::GetCursorPos(&point1); ?
? menu2->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, ?
? point1.x,point1.y,this); ?
? ?
? *pResult ? = ? 0; ?
? }??
偶然發(fā)現(xiàn)的一個(gè)有用的windows api SetROP2(int nDrawMode),現(xiàn)在將我對(duì)該api的使用的心得歸納如下: 該函數(shù)的主要的作用是根據(jù)nDrawMode設(shè)置的方式重新設(shè)定繪圖的方式,下面就不同的nDrawMode值具體解釋繪圖模式是如何改變的。 首先就nDrawMode的取值有以下的情況: /////////////////////////////////////////////////////////////////////////////////example///////////////////////////////////////////////////////////////////////// 總之,上述api的一個(gè)作用是在需要改變繪圖的模式時(shí),不需要重新設(shè)置畫筆,只需要設(shè)置不同的繪圖的模式即可達(dá)到相應(yīng)的目的。 |
#include<stdio.h>
struct a
{
?int b;
};
struct b
{
??? int a;
};
void main()
{
?a A;
?A.b = NULL;
?A.b = 1;
?
?b a;
?a.a = 3;
}
在C的環(huán)境下,會(huì)報(bào)錯(cuò),在C++的情況,這樣的操作就是允許的。
在C++的編譯器中,允許將結(jié)構(gòu)體名作為一個(gè)變量名來(lái)對(duì)待。
??????一個(gè)母親有兩個(gè)小孩(兩個(gè)指針),一個(gè)在廚房,一個(gè)在臥室,(屬于不同的代碼塊,其生存期不同)母親讓在廚房的小孩帶一塊蛋糕(指針指向的對(duì)象)給在臥室的小孩,這樣在臥室的孩子才肯寫作業(yè)。但這個(gè)在廚房的小孩比較淘氣,他在走出廚房時(shí)自己將蛋糕吃了,沒能帶出來(lái)。而在臥室的沒有吃到蛋糕,所以不肯完成他的作業(yè)。結(jié)果母親卻不知道臥室的孩子沒有吃到蛋糕,還以為作業(yè)完了。結(jié)果第二天她就被老師召喚到辦公室了。事情麻煩了。 這樣,那個(gè)在臥室的孩子就是野指針了,因?yàn)樗麤]有得到應(yīng)得的蛋糕,不能完成母親交給他的作業(yè)。
?
??????野指針是指那些你已經(jīng)釋放掉的內(nèi)存指針。當(dāng)你調(diào)用free(p)時(shí),你真正清楚這個(gè)動(dòng)作背后的內(nèi)容嗎?你會(huì)說(shuō)p指向的內(nèi)存被釋放了。沒錯(cuò),p本身有變化嗎?答案是p本身沒有變化。它指向的內(nèi)存仍然是有效的,你繼續(xù)讀寫p指向的內(nèi)存,沒有人能攔得住你。??
??????釋放掉的內(nèi)存會(huì)被內(nèi)存管理器重新分配,此時(shí),野指針指向的內(nèi)存已經(jīng)被賦予新的意義。對(duì)野指針指向內(nèi)存的訪問(wèn),無(wú)論是有意還是無(wú)意的,都為此會(huì)付出巨大代價(jià),因?yàn)樗斐傻暮蠊缤浇缭L問(wèn)一樣是不可預(yù)料的。?
??????釋放內(nèi)存后立即把對(duì)應(yīng)指針置為空值,這是避免野指針常用的方法。這個(gè)方法簡(jiǎn)單有效,只是要注意,當(dāng)然指針是從函數(shù)外層傳入的時(shí),在函數(shù)內(nèi)把指針置為空值,對(duì)外層的指針沒有影響。比如,你在析構(gòu)函數(shù)里把this指針置為空值,沒有任何效果,這時(shí)應(yīng)該在函數(shù)外層把指針置為空值。
void main()
{
? ? ? ? int i;
? ? ? ?
? ? ? ? if(i = -1)
? ? ? ? ? ? ? ? printf("True!\n");
? ? ? ? else
? ? ? ? ? ? ? ? printf("False!\n");
? ? ? ?
? ? ? ? if(i = 0)
? ? ? ? ? ? ? ? printf("True!\n");
? ? ? ? else
? ? ? ? ? ? ? ? printf("False!\n");
}
c++中delete前,判斷指針是否為0,有必要嗎?
有必要判斷pi = 0嗎? CODE:
if ( pi != 0 )
解答:
? ? delete pi; c++中,如果指針等于0的話,c++不會(huì)調(diào)用delete的。(因?yàn)閏++中隱式的進(jìn)行了判等) 如果顯示的判等,那么實(shí)際上這個(gè)測(cè)試會(huì)被執(zhí)行2次。 靜態(tài)與動(dòng)態(tài)內(nèi)存分配的兩個(gè)主要區(qū)別: 1. 靜態(tài)對(duì)象是有名字的變量,直接對(duì)其進(jìn)行操作;動(dòng)態(tài)對(duì)象是沒有名字的變量,通過(guò)指針間接地對(duì)它們進(jìn)行操作。 CODE: int *pia = new int (1024) 分配了一個(gè)沒有名字int類型的對(duì)象,對(duì)象初始值是1024。然后,表達(dá)式返回對(duì)象在內(nèi)存中的地址。2. 靜態(tài)對(duì)象的分配和釋放由編譯器自動(dòng)處理。動(dòng)態(tài)對(duì)象的分配和釋放必須由程序員自己顯式管理。 |
試題
4
:
void GetMemory( char *p )
{
? ?p = (char *) malloc( 100 );
}
void Test( void )
{
? ?char *str = NULL;
? ?GetMemory( str );
? ?strcpy( str, "hello world" );
? ?printf( str );
}
試題
5
:
char *GetMemory( void )
{? ?
? ???char p[] = "hello world";? ?? ?
? ???return p;??
}
void Test( void )
{? ?
? ???char *str = NULL;??
? ???str = GetMemory();? ?
? ???printf( str );? ?
}
試題
6
:
void GetMemory( char **p, int num )
{
? ???*p = (char *) malloc( num );
}
void Test( void )
{
? ???char *str = NULL;
? ???GetMemory( &str, 100 );
? ???strcpy( str, "hello" );
? ???printf( str );
}
試題
7
:
void Test( void )
{
? ???char *str = (char *) malloc( 100 );
? ???strcpy( str, "hello" );
? ???free( str );
? ???...??//
省略的其它語(yǔ)句
}
解答:
試題
4
傳入中
GetMemory( char *p )
函數(shù)的形參為字符串指針,在函數(shù)內(nèi)部修改形參并不能真正的改變傳入形參的值,執(zhí)行完
char *str = NULL;
GetMemory( str );
后的
str
仍然為
NULL
;
試題
5
中
? ???char p[] = "hello world";? ?
? ???return p;??
的
p[]
數(shù)組為函數(shù)內(nèi)的局部自動(dòng)變量,在函數(shù)返回后,內(nèi)存已經(jīng)被釋放。這是許多程序員常犯的錯(cuò)誤,其根源在于不理解變量的生存期。
試題
6
的
GetMemory
避免了試題
4
的問(wèn)題,傳入
GetMemory
的參數(shù)為字符串指針的指針,但是在
GetMemory
中執(zhí)行申請(qǐng)內(nèi)存及賦值語(yǔ)句
p = (char *) malloc( num );
后未判斷內(nèi)存是否申請(qǐng)成功,應(yīng)加上:
if ( p == NULL )
{
? ?...//
進(jìn)行申請(qǐng)內(nèi)存失敗處理
}
試題
7
存在與試題
6
同樣的問(wèn)題,在執(zhí)行
char *str = (char *) malloc(100);
后未進(jìn)行內(nèi)存是否申請(qǐng)成功的判斷;另外,在
free(str)
后未置
str
為空,導(dǎo)致可能變成一個(gè)
“
野
”
指針,應(yīng)加上:
str = NULL;
試題
6
的
Test
函數(shù)中也未對(duì)
malloc
的內(nèi)存進(jìn)行釋放。
剖析:
試題
4
~
7
考查面試者對(duì)內(nèi)存操作的理解程度,基本功扎實(shí)的面試者一般都能正確的回答其中
50~60
的錯(cuò)誤。但是要完全解答正確,卻也絕非易事。
對(duì)內(nèi)存操作的考查主要集中在:
(
1
)指針的理解;
(
2
)變量的生存期及作用范圍;
(
3
)良好的動(dòng)態(tài)內(nèi)存申請(qǐng)和釋放習(xí)慣。
在看看下面的一段程序有什么錯(cuò)誤:
swap( int* p1,int* p2 )
{
? ???int *p;
? ???*p = *p1;
? ???*p1 = *p2;
? ???*p2 = *p;
}
在
swap
函數(shù)中,
p
是一個(gè)
“
野
”
指針,有可能指向系統(tǒng)區(qū),導(dǎo)致程序運(yùn)行的崩潰。在
VC++
中
DEBUG
運(yùn)行時(shí)提示錯(cuò)誤
“Access Violation”
。該程序應(yīng)該改為:
swap( int* p1,int* p2 )
{
? ???int p;
? ???p = *p1;
? ???*p1 = *p2;
? ???*p2 = p;
}
試題1:
void test1()
{
? ?char string[10];
? ?char* str1 = "0123456789";
? ???strcpy( string, str1 );
}
試題2:
void test2()
{
? ?char string[10], str1[10];
? ???int i;
? ???for(i=0; i<10; i++)
? ???{
? ?? ???str1
= 'a';
? ???}
? ???strcpy( string, str1 );
}
試題3:
void test3(char* str1)
{
? ?char string[10];
? ?if( strlen( str1 ) <= 10 )
? ???{
? ?? ?? ?? ?strcpy( string, str1 );
? ???}
}
解答:
試題1字符串str1需要11個(gè)字節(jié)才能存放下(包括末尾的’\0’),而string只有10個(gè)字節(jié)的空間,strcpy會(huì)導(dǎo)致數(shù)組越界;
對(duì)試題2,如果面試者指出字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束可以給3分;如果面試者指出strcpy(string, str1)調(diào)用使得從str1內(nèi)存起復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不確定性可以給7分,在此基礎(chǔ)上指出庫(kù)函數(shù)strcpy工作方式的給10分;
對(duì)試題3,if(strlen(str1) <= 10)應(yīng)改為if(strlen(str1) < 10),因?yàn)閟trlen的結(jié)果未統(tǒng)計(jì)’\0’所占用的1個(gè)字節(jié)。
剖析:
考查對(duì)基本功的掌握:
(1)字符串以’\0’結(jié)尾;
(2)對(duì)數(shù)組越界把握的敏感度;
(3)庫(kù)函數(shù)strcpy的工作方式,如果編寫一個(gè)標(biāo)準(zhǔn)strcpy函數(shù)的總分值為10,下面給出幾個(gè)不同得分的答案:
2分
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
4分
void strcpy( char *strDest, const char *strSrc )
//將源字符串加const,表明其為輸入?yún)?shù),加2分
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
7分
void strcpy(char *strDest, const char *strSrc)??
{
//對(duì)源地址和目的地址加非0斷言,加3分
assert( (strDest != NULL) && (strSrc != NULL) );
while( (*strDest++ = * strSrc++)??!=??‘\0’ );
}
10分
//為了實(shí)現(xiàn)鏈?zhǔn)讲僮鳎瑢⒛康牡刂贩祷兀?分!
char * strcpy( char *strDest, const char *strSrc )??
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;??
while( (*strDest++ = * strSrc++) != ‘\0’ );
??return address;
}
類似的我們可以寫出一個(gè)10分的strlen函數(shù)
int strlen( const char *str )? ? //輸入?yún)?shù)const
{
? ???assert( strt != NULL );? ? //斷言字符串地址非0
? ???int len;
? ???while( (*str++) != '\0' )
? ???{??
? ?? ?? ?? ?len++;
? ???}
? ???return len;
}
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 | |||
10 | 11 | 12 | 13 | 14 | 15 | 16 | |||
17 | 18 | 19 | 20 | 21 | 22 | 23 | |||
24 | 25 | 26 | 27 | 28 | 29 | 30 | |||
31 | 1 | 2 | 3 | 4 | 5 | 6 |
常用鏈接
留言簿(6)
隨筆分類
隨筆檔案
- 2007年8月 (1)
- 2007年7月 (2)
- 2007年6月 (2)
- 2007年5月 (2)
- 2007年4月 (10)
- 2007年3月 (15)
- 2007年1月 (6)
- 2006年12月 (11)
- 2006年11月 (13)
文章分類
文章檔案
搜索
最新評(píng)論

- 1.?re: 常見內(nèi)存錯(cuò)誤
- 很全啊!
- --謝謝
- 2.?re: 也許有用(也談VC中ModifyStyle&ModifyStyleEx無(wú)法改變控件的Style)
- 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
- --y
- 3.?re: 用ITaskbarList接口操縱Windows任務(wù)欄程序按鈕的狀態(tài)
- 多謝
- --ggg
- 4.?re: 同步異步,長(zhǎng)連接短連接
- 很好的回答啊.....
- --cancan
- 5.?re: 同步異步,長(zhǎng)連接短連接
- 經(jīng)典
- --小哈哈
- 6.?re: C++內(nèi)存分配
- 想知道這篇文章來(lái)自哪本書的
- --幻景
- 7.?怎樣在word 中實(shí)現(xiàn)多組單選框
-
求助:怎樣在word 中實(shí)現(xiàn)多組單選框, 我想用word 做一些單選題, 謝謝!! hanzl007@163.com
還望幫忙啊
QQ 516521435 - --hansir007
- 8.?re: VC 界面庫(kù)
-
天下文章一大超啊, SYGUI那個(gè)界面庫(kù),明顯就是一個(gè)中國(guó)騙子抄人家的代碼,這里竟然和人家相提并論,唉....
- --路過(guò)
- 9.?re: 寫一個(gè)完美的strcpy / strlen 函數(shù)
- int len=0? len 要給個(gè)初值 么?
- --sun_njnu
- 10.?re: 自我反省
- 支持!
- --東東會(huì)會(huì)
- 11.?re: VC 界面庫(kù)
- 同感!Skin++支持的開發(fā)工具的版本和操作系統(tǒng)相對(duì)要廣泛。
- --Dom
- 12.?re: DICOM 構(gòu)成
-
@月戀星魂
有些鏈接可能已經(jīng)過(guò)期了 - --Jonson
- 13.?re: DICOM 構(gòu)成
- 問(wèn)一下DICOM標(biāo)準(zhǔn)DICOM 標(biāo)準(zhǔn)PS 3.3 部分怎么查不到啊
- --月戀星魂
- 14.?re: VC 界面庫(kù)[未登錄]
- 比較了一下,Skin++的效果最好!
- --me
- 15.?re: 開發(fā)心得
-
代碼需要不斷的重構(gòu), 推薦你看看《重構(gòu)》這本書
重構(gòu)-改善既有代碼的設(shè)計(jì)(中文版) - --Galaxy
- 16.?re: 自我反省
- 有道理,看來(lái)我還停留在"從前的我"
- --pengkuny
- 17.?re: 寫一個(gè)完美的strcpy / strlen 函數(shù)
- 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
- --彭剛pgmuse@126.com
- 18.?re: ListCtrl的總結(jié)
- 不錯(cuò)呀,謝謝
- --melody
- 19.?re: 寫一個(gè)完美的strcpy / strlen 函數(shù)
- 謝謝收下 參照自學(xué)習(xí)之用
- --謝謝