Guide to Advanced Programming in C.docx
- 文档编号:28226731
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:46
- 大小:48.88KB
Guide to Advanced Programming in C.docx
《Guide to Advanced Programming in C.docx》由会员分享,可在线阅读,更多相关《Guide to Advanced Programming in C.docx(46页珍藏版)》请在冰豆网上搜索。
GuidetoAdvancedProgramminginC
GuidetoAdvancedProgramminginC
Back
06Jan2014
Clanguageislanguageofchoiceforsystemsprogramming,embeddedsystemsandalsoviableoptionformanyotherapplications.WhileitisnotlikelytohaveseriousinterestincomputerprogrammingandnottobetouchedbyC,itisextremelychallengingtounderstandallitsaspectsandshadycorners.Thisarticleattemptstoprovidedensematerialtoilluminatesomeofthoseareas.Namely:
integerpromotions,memoryallocation,arraytopointerconversions,explicitinlining,interpositioningandvectorconversions.
IntegerOverflowsandPromotions
MostofusCprogrammerstendtoassumethatbasicoperationswithintegersaresafeandexerciseprudenceelsewhere.Actuallyitisnotthathardtorunintotrouble.Considerfollowingcode:
intmain(intargc,char**argv){
longi=-1;
if(i printf("OK\n"); } else{ printf("error\n"); } return0; } Whathappensisthatvariableiisconvertedtounsignedinteger.Thusitsvalueisnolonger-1,butmaximumvalueofsize_t,whichhappenstoberesulttypeofsizeofoperator.ThereasonwhyisthatsoisdescribedbychapterUsualarithmeticconversionsoftheC99/C11standard: "Iftheoperandthathasunsignedintegertypehasrankgreaterorequaltotherankofthetypeoftheotheroperand,thentheoperandwithsignedintegertypeisconvertedtothetypeoftheoperandwithunsignedintegertype." Thesize_tisbytheCstandarddefinedasunsignedintegerwithsizeatleast16bits.Usuallysize_tcorrespondswithlongofgivenarchitecture.Thatmakesthesizeofintandsize_tatleastequalandaboveruleenforcesconversiontounsignedinteger. Thatbringustoportabilityissueswithintegersizes.TheCstandarddoesnotexactlydefinesizesofshort,int,long,longlongandtheirunsignedversions.Onlyminimumsizesareenforced.Forsakeofexampleconsiderx86_64architecture.longonLinuxis64-bitwhereason64-bitWindowsitis32-bit.Commonapproachtomakecodemoreportableistouselength-specifictypeslikeuint16_torint32_tdefinedbyC99'sstdint.hheaderfile.Threekindsofintegertypesaredefinedthere: ∙withexactlyspecifiedsize: uint8_tuint16_t,int32_t,etc. ∙smallesttypewithatleastspecifiedsize: uint_least8_t,uint_least16_t,int_least32_t,etc. ∙mostefficienttypewithatleastspecifiedsize: uint_fast8_t,uint_fast16_t,int_fast32_t,etc. Unfortunatelyusingstdint.hwillnotprotectusfromalltrouble.The"integralpromotionrule"oftheCstandardsays: Ifanintcanrepresentallvaluesoftheoriginaltype,thevalueisconvertedtoanint;otherwise,itisconvertedtoanunsignedint.Thesearecalledtheintegerpromotions.Allothertypesareunchangedbytheintegerpromotions. Thusfollowingcodewillreturn65536on32-bitplatforms,but0on16-bitplatforms. uint32_tsum() { uint16_ta=65535; uint16_tb=1; returna+b; } Theintegerpromotionspreservevalueincludingsign.Whethera‘‘plain’’charistreatedassignedisimplementation-defined." Howchartypeisimplementedusuallydependonhardwarearchitectureand/orOSanditisusuallyspecifiedbyABI(ApplicationBinaryInterface)ofparticularplatform.Ifyoucaretofindoutonyourown,incasecharispromotedassignedchar,followingcodewillprint-128,-127(x86arch.)otherwise128,129.TheGCChas-funsigned-charswitchtoforceunsignedpromotiononx86architecture. charc=128; chard=129; printf("%d,%d\n",c,d); MemoryAllocationandManagement malloc,calloc,realloc,free Themallocallocatesuninitializedmemoryobjectwithsizespecifiedinbytes.Whatshouldhappenifsizeis0dependsonOSimplementationorinotherwordsneitherCnorPOSIXstandardspecifythebehavior. Ifthesizeofthespacerequestedis0,thebehaviorisimplementation-defined: thevaluereturnedshallbeeitheranullpointerorauniquepointer. malloc(0)usuallygoeswithreturningvaliduniquepointer.Eitherwayreturnvaluecouldbepassedasargumentoffreewithoutendingupwitherror.IncaseofNULLpointerfreedoesnoaction. Thereforeifsizeargumentisresultofanexpression,makesuretotestforintegeroverflow. size_tcomputed_size; if(elem_size&&num>SIZE_MAX/elem_size){ errno=ENOMEM; err(1,"overflow"); } computed_size=elem_size*num; Forcommoncaseofallocatingasequencewithequallysizedelements,considertousecallocinsteadofcalculatingsizewithexpression.Additionallyitwillinitializeallocatedmemorytozero.Forreleasingallocatedspaceusefreeasusual. Thereallocwillchangesizeofalreadyallocatedmemoryobject.Functionreturnspointertopossiblynewmemorylocationwithsamecontenttothelesserofthenewandoldsizes.Ifnewsizeislarger,additionalspaceisleftuninitialized.IfprovidedpointertooldobjectisNULLandsizenon-zerobehaviorisequaltomalloc.Ifnewsizeiszeroandprovidedmemoryobjectnon-NULL,behaviorofreallocisOSdepended. Mostimplementationswillattempttofreememoryofanobjectandreturnvaluethatmalloc(0)wouldreturnorreturnNULL.ForinstanceWindowswillreleasememoryandreturnNULL.OpenBSDwillreleasetooandreturnpointertozero-sizedobject. IncaseoffailurereallocshallreturnNULLandleaveprovidedmemoryobjectintact.Thusitisimportantnotonlytocheckforintegeroverflowofsizeargument,butalsotocorrectlyhandleobjectsizeifreallocfails. #include #include #include #include #defineVECTOR_OK0 #defineVECTOR_NULL_ERROR1 #defineVECTOR_SIZE_ERROR2 #defineVECTOR_ALLOC_ERROR3 structvector{ int*data; size_tsize; }; intcreate_vector(structvector*vc,size_tnum){ if(vc==NULL){ returnVECTOR_NULL_ERROR; } vc->data=0; vc->size=0; /*checkforintegerandSIZE_MAXoverflow*/ if(num==0||SIZE_MAX/num errno=ENOMEM; returnVECTOR_SIZE_ERROR; } vc->data=calloc(num,sizeof(int)); /*callocfaild*/ if(vc->data==NULL){ returnVECTOR_ALLOC_ERROR; } vc->size=num*sizeof(int); returnVECTOR_OK; } intgrow_vector(structvector*vc){ void*newptr=0; size_tnewsize; if(vc==NULL){ returnVECTOR_NULL_ERROR; } /*checkforintegerandSIZE_MAXoverflow*/ if(vc->size==0||SIZE_MAX/2 errno=ENOMEM; returnVECTOR_SIZE_ERROR; } newsize=vc->size*2; newptr=realloc(vc->data,newsize); /*reallocfaild;vectorstaysintactsizewasnotchanged*/ if(newptr==NULL){ returnVECTOR_ALLOC_ERROR; } /*uponsuccess;updatenewaddressandsize*/ vc->data=newptr; vc->size=newsize; returnVECTOR_OK; } AvoidingFatalErrors Generalapproachtoavoidproblemswithdynamicmemoryallocationistowritecodeashumblyanddefensivelyascircumstancesallow.Herearemostcommonproblemsandafewapproacheshowtoavoidthem. 1)Doublefreecorruption Couldbecausedbycallingfreewithpointer,whichiseitherNULLpointer,pointerwhichwasnotallocatedwithmallocfamilyfunctionorfree/reallocwasalreadycalledwiththatpointer.Tomakecodemoreresistanttosucherrorsconsiderfollowingpoints: ∙InitializepointersupondeclarationwithNULLincaseyoucannotpassvalidpointerimmediately. ∙BothGCCandClanghave-Wuninitializedswitchtowarnaboutuninitializedvariables ∙Donotusesamepointervariableforbothstaticallyanddynamicallyallocatedmemory ∙AftercallingfreesetpointerbacktoNULLsoifyouaccidentallycallitagainitwillnotcauseerror ∙Toindicatedoublefreeuseassertoritsalternativewhiletestinganddebugging char*ptr=NULL; /*...*/ voidnullfree(void**pptr){ void*ptr=*pptr; assert(ptr! =NULL) free(ptr); *pptr=NULL; } 2)Accessingmemorythroughuninitializedornullpointer UsingrulesaboveyourcodeshallonlybedealingwithNULLorvalidpointers.CheckforNULLatbeginningoffunctionorblockswhicharedereferencingpointerstodynamicallyallocatedmemory. 3)Accessingmemoryoutsideofallocatedboundaries Accessingmemoryobjectoutsideit'sboundariesdoesnotnecessarilycauseprogramtocrash.ProgrammightcontinuetooperateusingcorrupteddatawithpossiblydangerousbehaviororItisalsopossibletakeadvantageofsuchoperationsandalterbehaviorofprogramtoaccessotherwiserestrictedinformationoreveninjectexecutablecode.Pedanticmanualcheckingforboundariesofarraysanddynamicallyallocatedmemoryobjectsisprimaryapproachtopreventtheserisks.Theinformationaboutboundariesofmemoryobjectshastobetrackedmanually.Sizeofarrayscanbedeterminedwithsizeofoperator,butafterarrayisconvertedtopointere.g.duringfunctioncallsizeofwillreturnsizeofapointeritselfinsteadofarray. TheboundscheckinginterfaceAnnexKoftheC11standarddefinesnewsetoflibraryfunctionsprovidingalternativeseasiertousesecurelytocommonpartsofstandardlibrary(suchasstringandI/Omanipulation).Thereareopen-sourceimplementationslike[theslibclibrary][slibc],buttheinterfaceisnotwidelyadoptedyet.BSDbasedsystems(alsoMacOSX)providestrlcpy,strlcatfunctionsforbetterstringmanipulation.Theyareavailableforothersystemthroughlibbsdlibrary. Manyoperatingsystemsprovideinterfacetocontrolaccessovermemoryregionstoprotectmemoryagainstunintendedread/writeoperationssuchasPosixmprotect.Thesemechanismsusuallyapplytowholememorypages. AvoidingMemoryLeaks Memoryleaksarecausedbynotreleasingdynamicmemorywhichisnolongerusedbyprogram.Thu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Guide to Advanced Programming in