ããã¯ããã°ã©ãã³ã°ã«ãåœãŠã¯ãŸããC ++ã§ã®ããã°ã©ãã³ã°ã«ãåœãŠã¯ãŸããŸãã ãã®èšäºã§ã¯ãã»ãšãã©ãã¹ãŠã®è€éãªã¯ã©ã¹ã«ååšãããä»®æ³ããŒãã«ã€ã³ããã¯ã¹ããšåŒã°ããèšèªã®éèŠãªæŠå¿µãšãããã誀ã£ãŠç Žæããå¯èœæ§ãããæ¹æ³ã«ã€ããŠèª¬æããŸãã ããã«ããããããã°ãšã©ãŒãçºçãã«ãããªããŸãã æåã«ããããäœã§ããããæãåºãã次ã«ããã«ã©ã®ããã«ããããŠäœãå£ãããã«ã€ããŠã®ç§ã®èããå ±æããŸãã
æ®å¿µãªããšã«ããã®èšäºã§ã¯ãäœã¬ãã«ã«é¢é£ããå€ãã®è°è«ããããŸãã ããããæ®å¿µãªããããã¯ãåé¡ã説æããŠããŸããã åæã«ã64ãããããã°ã©ã ã®ãã«ãã¢ãŒãã§Visual C ++ã³ã³ãã€ã©ã³ã³ãã€ã©ã®å€§éšåã«ã€ããŠèšäºãæžãããããšãäºçŽããŸããä»ã®ã³ã³ãã€ã©ãšç°ãªãã¢ãŒããã¯ãã£ã®ããã°ã©ã ã®çµæã¯ç°ãªãå ŽåããããŸãã
ä»®æ³ããŒãã«ãã€ã³ã¿ãŒ
çè«ã«ããã°ãvptrãã€ã³ã¿ãŒïŒä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒããŸãã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒïŒã¯ãå°ãªããšã1ã€ã®ä»®æ³ã¡ãœãããæã€ãã¹ãŠã®ã¯ã©ã¹ã«ååšããŸãã ã©ããªåç©ãªã®ãã詳ããèŠãŠãããŸãã ãããè¡ãã«ã¯ãC ++ã§ç°¡åãªãã¢ããã°ã©ã ãäœæããŸãã
#include <iostream> #include <iomanip> using namespace std; int nop() { static int nop_x; return ++nop_x; // , ! }; class A { public: unsigned long long content_A; A(void) : content_A(0xAAAAAAAAAAAAAAAAull) { cout << "++ A has been constructed" << endl;}; ~A(void) { cout << "-- A has been destructed" << endl;}; void function(void) { nop(); }; }; void PrintMemory(const unsigned char memory[], const char label[] = "contents") { cout << "Memory " << label << ": " << endl; for (size_t i = 0; i < 4; i++) { for (size_t j = 0; j < 8; j++) cout << setw(2) << setfill('0') << uppercase << hex << static_cast<int> (memory[i * 8 + j]) << " "; cout << endl; } } int main() { unsigned char memory[32]; memset(memory, 0x11, 32 * sizeof(unsigned char)); PrintMemory(memory, "before placement new"); new (memory) A; PrintMemory(memory, "after placement new"); reinterpret_cast<A *>(memory)->~A(); system("pause"); return 0; };
æ¯èŒç倧éã®ã³ãŒãããããŸããããã®åäœã®ããžãã¯ã¯ããªãæçœãªã¯ãã§ãã32ãã€ããã¹ã¿ãã¯ã«å²ãåœãŠããã0x11ã®å€ã§åããããŸãïŒããã¯ã¡ã¢ãªå ã®ãã¬ããŒãžããšèŠãªãããŸãïŒã 次ã«ããããã®32ãã€ãã®äžã«ã é 眮newæŒç®åã䜿çšããŠããªãåçŽãªã¯ã©ã¹Aãªããžã§ã¯ããäœæãããæåŸã«ã¡ã¢ãªã®å 容ãåºåããããã®åŸãããã°ã©ã ã¯ãªããžã§ã¯ããç Žæ£ããŠå®è¡ãå®äºããŸãã 以äžã¯ããã®ããã°ã©ã ã®åºåã§ãïŒMicrosoft Visual Studio 2012ãx64ïŒã
Memory before placement new: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ++ A has been constructed Memory after placement new: AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed Press any key to continue . . .
ã¡ã¢ãªå ã®ã¯ã©ã¹ã®ãµã€ãºã¯8ãã€ãã§ãããå¯äžã®ã¡ã³ããŒã§ããunsigned long long content_Aã®ãµã€ãºã«çããããšã¯ç°¡åã«ããããŸãã
ä»®æ³é¢æ°ãvoidé¢æ°ïŒvoidïŒé¢æ°ã®å®£èšã«è¿œå ããŠãããã°ã©ã ãå°ãè€éã«ããŸãããã
virtual void function(void) {nop();};
ããã°ã©ã åºåïŒä»¥äžã§ã¯ãæ°èŠé 眮åã«ã¡ã¢ãªãé€ããŠåºåã®äžéšã®ã¿ã衚瀺ãããä»»æã®ããŒãæŒããŸã...ïŒïŒ
++ A has been constructed Memory after placement new: F8 D1 C4 3F 01 00 00 00 AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed
ç¹°ãè¿ãã«ãªããŸãããã¡ã¢ãªå ã®ã¯ã©ã¹ãµã€ãºã16ãã€ãã«ãªã£ãããšã¯ç°¡åã«ããããŸãã æåã®8ãã€ãã¯ãä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒã§å ããããŠããŸãã ããã°ã©ã ã®ãã®éå§æã®ãã€ã³ã¿ãŒã¯0x000000013FC4D1F8ã§ããïŒIntel64ã¯ãªãã«ãšã³ãã£ã¢ã³ã®ãã€ãé ã䜿çšããŠããããããã€ã³ã¿ãŒãšcontent_Aã¯ã¡ã¢ãªå ã§ãæ¡åŒµããããŸãããcontent_Aã®å Žåãããã«èšãããšã¯ã§ããŸããïŒã
ä»®æ³ã¡ãœããããŒãã«ã¯ãä»®æ³ã¡ãœãããžã®ãã€ã³ã¿ãŒããªã¹ããããèªåçã«çæãããã¡ã¢ãªå ã®ç¹å¥ãªæ§é ã§ãã functionïŒïŒã¡ãœããããã¯ã©ã¹Aãžã®ãã€ã³ã¿ãŒã«é¢ããŠã³ãŒãã®ã©ããã§åŒã³åºãããå ŽåãA :: functionïŒïŒé¢æ°ãçŽæ¥åŒã³åºã代ããã«ãç®çã®ãªãã»ããã§ä»®æ³ã¡ãœããã®ããŒãã«ã«ããé¢æ°ãåŒã³åºãããŸã-ãã®åäœã¯ããªã¢ãŒãã£ãºã ãå®è£ ããŸãã ä»®æ³é¢æ°ããŒãã«èªäœã以äžã«ç€ºããŸãïŒ/ FAsã¹ã€ããã䜿çšããŠã³ã³ãã€ã«ããããšã§ååŸããŸããããã«ãã¢ã»ã³ãã©ã³ãŒãå ã®é¢æ°ã®ããå¥åŠãªååã«æ³šæããŠãã ãããã ååã®ãã³ã°ãªã³ã° ããééããŸããïŒã
CONST SEGMENT ??_7A@@6B@ DQ FLAT:??_R4A@@6B@ ; A::'vftable' DQ FLAT:?function@A@@UEAAXXZ CONST ENDS
__declspecïŒnovtableïŒ
ååãšããŠãä»®æ³ã¯ã©ã¹ããŒãã«ãäžèŠãªå ŽåããããŸãã ã¯ã©ã¹Aãã€ã³ã¹ã¿ã³ã¹åããªããšä»®å®ããŸããã€ã³ã¹ã¿ã³ã¹åããå Žåã¯ãé±æ«ãšç¥æ¥ã®ã¿ã«ãåæã«1ã€ã®ä»®æ³é¢æ°ãåŒã³åºãããªãããã«æ³šæããŠãã ããã ããã¯ãæœè±¡ã¯ã©ã¹ã®å Žåã«ã¯ããªãäžè¬çãªç¶æ³ã§ããã¯ã©ã¹ãæœè±¡ã¯ã©ã¹ã®å Žåãã€ã³ã¹ã¿ã³ã¹åã§ããªãããšãããã£ãŠããŸãã ãŸããã å®éãé¢æ°ïŒvoidïŒé¢æ°ãæœè±¡ãšããŠã¯ã©ã¹Aã§å®£èšãããå Žåãä»®æ³ã¡ãœããã®ããŒãã«ã¯æ¬¡ã®ããã«ãªããŸãã
CONST SEGMENT ??_7A@@6B@ DQ FLAT:??_R4A@@6B@ ; A::'vftable' DQ FLAT:_purecall CONST ENDS
æããã«ããã®ãããªé¢æ°ãåŒã³åºãããšãããšãèªåã®è¶³ã®è °çã«ãªããŸãã
質åãçºçããŸãïŒã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åãããªãå Žåããªãä»®æ³ããŒãã«ãã€ã³ã¿ãŒãèšå®ããã®ã§ããïŒ ã³ã³ãã€ã©ãäœåãªã³ãŒããçæããªãããã«ããããã«ã__ declspecïŒnovtableïŒã®åœ¢åŒã§åœä»€ãäžããããšãã§ããŸãïŒæ³šæïŒãã€ã¯ããœããåºæïŒïŒã __declspecïŒnovtableïŒå±æ§ã䜿çšããŠãä»®æ³é¢æ°ã§ãµã³ãã«ã¯ã©ã¹ãæžãçŽããŸãã
class __declspec(novtable) A { .... }
ããã°ã©ã ã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
++ A has been constructed Memory after placement new: 11 11 11 11 11 11 11 11 AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed
ãŸãããªããžã§ã¯ãã®ãµã€ãºãå€æŽãããŠããªããšããäºå®ã«æ³šæããŠãã ãããããã§ã16ãã€ããå¿ èŠãšããŸãã åèšãããšã__ declspecïŒnovtableïŒå±æ§ãå°å ¥ããåŸã2ã€ã®çžéç¹ã®ã¿ãçŸããŸããããŸããä»®æ³ã¡ãœããããŒãã«ã®ã¢ãã¬ã¹ã以åã«ãã£ãå Žæã«ãåæåãããŠããªãã¡ã¢ãªé åããããŸãã 第äºã«-ã¢ã»ã³ãã©ã³ãŒãã§ã¯ãã¯ã©ã¹Aã®ä»®æ³ã¡ãœããã®ããŒãã«ã¯ããååšããŸããã ãã ããä»®æ³ããŒãã«ãã€ã³ã¿ãŒã¯ãŸã ååšãã8ãã€ãã®ãéãããæ®ã£ãŠããŸãã ããã¯èŠããŠããå¿ èŠããããŸã...
ç¶æ¿
ä»®æ³ããŒãã«ãã€ã³ã¿ãŒã䜿çšããŠæœè±¡ã¯ã©ã¹ããæãåçŽãªç¶æ¿ãå®è£ ããããã«äŸãæžãæããŸãã
class __declspec(novtable) A // { public: unsigned long long content_A; A(void) : content_A(0xAAAAAAAAAAAAAAAAull) { cout << "++ A has been constructed" << endl;}; ~A(void) { cout << "-- A has been destructed" << endl;}; virtual void function(void) = 0; }; class B : public A // A { public: unsigned long long content_B; B(void) : content_B(0xBBBBBBBBBBBBBBBBull) { cout << "++ B has been constructed" << endl;}; ~B(void) { cout << "-- B has been destructed" << endl;}; virtual void function(void) { nop(); }; };
ãŸããã¯ã©ã¹Aã®ä»£ããã«ãã¡ã€ã³ããã°ã©ã ã§ã¯ã©ã¹BãäœæïŒããã³ç Žæ£ïŒãããããã«ããŸãã
.... new (memory) B; PrintMemory(memory, "after placement new"); reinterpret_cast<B *>(memory)->~B(); ....
ããã°ã©ã ã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
++ A has been constructed ++ B has been constructed Memory after placement new: D8 CA 2C 3F 01 00 00 00 AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
äœãèµ·ãã£ãããææ¡ããŠã¿ãŸãããã ã³ã³ã¹ãã©ã¯ã¿ãŒB :: BïŒïŒãåŒã³åºãããŸããã ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãå®è¡ãããåã«ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ããã³ã³ã¹ãã©ã¯ã¿ãŒA :: AïŒïŒãåŒã³åºããŸãã ãŸããä»®æ³ããŒãã«ãã€ã³ã¿ãŒãåæåããå¿ èŠããããŸããã__ declspecïŒnovtableïŒå±æ§ã®ãããåæåãããŸããã§ããã 次ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã¯content_Aãã£ãŒã«ãã®å€ã0xAAAAAAAAAAAAAAAAAullïŒã¡ã¢ãªã®2çªç®ã®ãã£ãŒã«ãïŒã«èšå®ããã³ã³ã¹ãã©ã¯ã¿ãŒB :: BïŒïŒã«å¶åŸ¡ãè¿ããŸãã
ãªããžã§ã¯ãBã«ã¯__declspecïŒnovtableïŒå±æ§ããªããããã³ã³ã¹ãã©ã¯ã¿ãŒã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒïŒã¡ã¢ãªå ã®æåã®ãã£ãŒã«ãïŒãã¯ã©ã¹Bä»®æ³ã¡ãœããããŒãã«ã«èšå®ãã次ã«content_Bã0xBBBBBBBBBBBBBBBBBullïŒã¡ã¢ãªå ã®3çªç®ã®ãã£ãŒã«ãïŒã«èšå®ããã¡ã€ã³ããã°ã©ã ã«å¶åŸ¡ãè¿ããŸãã ã¡ã¢ãªã®å 容ãããã¯ã©ã¹Bã®ãªããžã§ã¯ããæ£ããæ§ç¯ãããããšãç°¡åã«ç解ã§ãããã®ã³ã³ããã¹ãã§ã¯äžèŠãªæäœãã¹ããããããããšã¯ããžãã¯ããæããã§ãã æ··ä¹±ããŠããå ŽåïŒäžèŠãªæäœãšã¯ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ä»®æ³ããŒãã«ãžã®ãã€ã³ã¿ãŒãåæåããããšãæå³ããŸãã
èŠéãããæäœã¯1ã€ã ãã®ããã«æããŸã-ãã€ã³ãã¯ãããåãé€ãããšã§ããïŒ ããããããã°ã©ã ãåãæœè±¡ã¯ã©ã¹ããç¶æ¿ããäœåãã®ã¯ã©ã¹ãæã£ãŠããå Žåã1ã€ã®èªåçæã³ãã³ããåé€ãããšãããã©ãŒãã³ã¹ã«æ·±å»ãªåœ±é¿ãäžããå¯èœæ§ããããŸãã ãããŠãããã¯åœ±é¿ããŸãã ä¿¡ããããªãïŒ
Memseté¢æ°
memsetïŒïŒé¢æ°ã®äž»ãªèãæ¹ã¯ãã¡ã¢ãªé åãäžå®ã®å€ïŒã»ãšãã©ã®å ŽåãŒãïŒã§åããããšã§ãã Cã§ã¯ãæ§é äœã®ãã¹ãŠã®ãã£ãŒã«ãããã°ããåæåããããã«äœ¿çšã§ããŸãã ãŸããä»®æ³ããŒãã«ãã€ã³ã¿ãŒããªãå ŽåãC ++ã¯ã©ã¹ãšã¡ã¢ãªãã±ãŒã·ã§ã³ã®Cæ§é äœã®éãã¯äœã§ããïŒ ååãšããŠãäœããããŒã¿-ãããã¯ããŒã¿ã§ãã æ¬åœã«åçŽãªã¯ã©ã¹ïŒC ++ 11ã®çšèª- æšæºããã€ã¹ã®å ïŒãåæåããã«ã¯ãmemsetïŒïŒé¢æ°ã䜿çšããããšãã§ããŸãã ããããçè«çã«ã¯ãmemsetïŒïŒé¢æ°ã䜿çšããŠäžè¬ã«ãã¹ãŠã®ã¯ã©ã¹ãåæåã§ããŸãããçµæã¯ã©ããªããŸããïŒ èª€ã£ãmemsetïŒïŒãäžåºŠã«ãããšãä»®æ³ããŒãã«ãã€ã³ã¿ãŒã䜿çšã§ããªããªãããšããããŸãã ããããããã«åé¡ãçºçããŸããã¯ã©ã¹ã__declspecïŒnovtableïŒãšããŠå®£èšãããŠããå Žåã§ããããã¯å¯èœã§ããïŒ
åçïŒããã¯å¯èœã§ãããæ éã«ããã§ããŸããã
ã¯ã©ã¹ã次ã®ããã«æžãæããŸããã¯ã©ã¹Aã®ã³ã³ãã³ãå šäœã0xAAã«èšå®ããã¯ã€ãã¡ãœãããè¿œå ããŸãã
class __declspec(novtable) A // { public: unsigned long long content_A; A(void) { cout << "++ A has been constructed" << endl; wipe(); }; // { cout << "++ A has been constructed" << endl; }; ~A(void) { cout << "-- A has been destructed" << endl;}; virtual void function(void) = 0; void wipe(void) { memset(this, 0xAA, sizeof(*this)); cout << "++ A has been wiped" << endl; }; }; class B : public A // A { public: unsigned long long content_B; B(void) : content_B(0xBBBBBBBBBBBBBBBBull) { cout << "++ B has been constructed" << endl;}; // { // cout << "++ B has been constructed" << endl; // A::wipe(); // }; ~B(void) { cout << "-- B has been destructed" << endl;}; virtual void function(void) {nop();}; };
ãã®å Žåã®ããã°ã©ã ã®åºåã¯éåžžã«æåŸ ãããŸãã
++ A has been constructed ++ A has been wiped ++ B has been constructed Memory after placement new: E8 CA E8 3F 01 00 00 00 AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
ãããŸã§ã®ãšããããã¹ãŠãããŸãæ©èœããŠããŸãã
ãã ããã³ã³ã¹ãã©ã¯ã¿ãŒã®è¡ãã³ã¡ã³ãåããŠãããã«ç¶ãè¡ã®ã³ã¡ã³ããå€ãããšã§ãwipeïŒïŒé¢æ°åŒã³åºãã®å Žæããããã«å€æŽããå¿ èŠããããŸãã ä»®æ³é¢æ°ïŒïŒé¢æ°ã®æåã®åŒã³åºãã§ã¯ãä»®æ³ããŒãã«ãã€ã³ã¿ãŒãç ŽæããŠãããããã©ã³ã¿ã€ã ãšã©ãŒãçºçããŸãã
++ A has been constructed ++ B has been constructed ++ A has been wiped Memory after placement new: AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
ãªããããèµ·ãã£ãã®ã§ããïŒ ã¯ã©ã¹Bã³ã³ã¹ãã©ã¯ã¿ãŒãä»®æ³ã¡ãœããããŒãã«ãžã®ãã€ã³ã¿ãŒãåæåããåŸã«ãwipeïŒïŒé¢æ°ãåŒã³åºãããŸããã ãã®çµæããã®ãã€ã³ã¿ãŒã¯å£åããŸããã ã€ãŸãã__ declspecïŒnovtableïŒã§å®£èšãããŠããå Žåã§ããä»®æ³ããŒãã«ãã€ã³ã¿ãŒã§ã¯ã©ã¹ãç¡å¹ã«ããªãã§ãã ããã å®å šãªãŒãåã¯ãã€ã³ã¹ã¿ã³ã¹åãããªãã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã®ã¿é©åã§ããããã®å Žåã§ã现å¿ã®æ³šæãæã£ãŠè¡ãå¿ èŠããããŸãã
Memcpyé¢æ°
memcpyïŒïŒã®å Žåãç»åã¯ãŸã£ããåãã§ãã ç¹°ãè¿ããŸãããçè«çã«ã¯ãã¡ã¢ãªå ã®æšæºããã€ã¹ã§åãã³ããŒããããã«äœ¿çšã§ããŸãã ãã ããå®è·µã«ãã£ãŠå€æãããšãäžéšã®ããã°ã©ããŒã¯ãå¿ èŠãªå Žåãšããã§ãªãå Žåã«äœ¿çšããããšã奜ã¿ãŸãã ã¡ã¢ãªã«æšæºããã€ã¹ããªãã¿ã€ãã®å ŽåãmemcpyïŒïŒé¢æ°ã®äœ¿çšã¯ããã€ã¢ã¬ã©ã®æ»ãæž¡ã綱枡ãã®ãããªãã®ã§ãã1ã€ã®ééãã¯èŽåœçãªçµæã«ã€ãªããå¯èœæ§ããããããã¯ãšãŠã€ããªãç°¡åã§ãã äŸãšããŠïŒ
class __declspec(novtable) A { .... A(const A &source) { memcpy(this, &source, sizeof(*this)); } virtual void foo() { } .... }; class B : public A { .... };
ã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãæœè±¡ã¯ã©ã¹ã®ä»®æ³ããŒãã«ãžã®ãã€ã³ã¿ãŒã«ãããžã¿ã«ãœãŠã«ãæããã®ãäœã§ãæžã蟌ãããšãã§ããŸããæ£ããå€ã¯ãšã«ããé 眮ãããŸãã ãã ããä»£å ¥æŒç®åã®å®è£ ã§ã¯ãmemcpyïŒïŒé¢æ°ã䜿çšããããšã¯ã§ããªããªããŸããã
class __declspec(novtable) A { .... A &operator =(const A &source) { memcpy(this, &source, sizeof(*this)); return *this; } virtual void foo() { } .... }; class B : public A { .... };
ããã§ãä»£å ¥æŒç®åãšã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒãå®è³ªçã«åããã®ã§ãããšããäºå®ã«ã©ã®ããã«æ £ããŠããããæãåºããŠãã ããã ãããããã¹ãŠãããã»ã©æªãããã§ã¯ãããŸããïŒå®éã«ã¯ãä»£å ¥æŒç®åã®ã³ãŒãã¯æ£ããåäœããããšããã§ããŸãããããã¯æ£ããããã§ããããããæã¯ãã®ããã«åœ¢æãããŠããããã§ãã ãã®ã³ãŒãã§ã¯ãå¥ã®ãªããžã§ã¯ãããä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒãã³ããŒãããŸãããã©ã®ãããªçµæã«ãªããã¯ããããŸããã
PVS-Studio
ãã®èšäºã¯ãç¥ç§çãª__declspecïŒnovtableïŒã«é¢ãã詳现ãªèª¿æ»ã®çµæãšããŠç»å ŽããŸããããŸããé«ã¬ãã«ã³ãŒãã§memsetïŒïŒããã³memcpyïŒïŒé¢æ°ã䜿çšããããšãå¯èœãã€äžå¯èœãªå ŽåããããŸãã éçºè ã¯æã ã PVS-Studioã¢ãã©ã€ã¶ãŒãä»®æ³ããŒãã«ãã€ã³ã¿ãŒã«é¢ããèŠåãé »ç¹ã«çæããããšãå ±åããŠããŸãã ããã°ã©ãã¯ã__ declspecïŒnovtableïŒãååšããå Žåãä»®æ³ã¡ãœããããŒãã«ãŸãã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒã¯ååšããªããšèããŠããŸãã ç§ãã¡ã¯ãã®åé¡ã«æ éã«å¯ŸåŠãå§ãããããããã»ã©åçŽã§ã¯ãªãããšã«æ°ä»ããŸããã
ããã¯èŠããŠããå¿ èŠããããŸãã ã¯ã©ã¹ã®å®£èšæã«__declspecïŒnovtableïŒã䜿çšããå Žåãããã¯ã¯ã©ã¹ã«ä»®æ³ã¡ãœããããŒãã«ãžã®ãã€ã³ã¿ãŒãå«ãŸããŠããªãããšãæå³ããŸããïŒ ãããããã®ãã€ã³ã¿ãŒã¯åæåãããŠãããã©ããã§ã-ããã¯ãŸã£ããå¥ã®è³ªåã§ãã
__declspecïŒnovtableïŒã§å®£èšãããåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§äœ¿çšãããå Žåã«ã®ã¿ãã¢ãã©ã€ã¶ãŒã«memsetïŒïŒ/ memcpyïŒïŒé¢æ°ãèªãããŸããã
ãããã«
æ®å¿µãªããããã®èšäºã¯ç¶æ¿ã«é¢é£ããå€ãã®è³æãã«ããŒã§ããŸããã§ããïŒããšãã°ãå€éç¶æ¿ã®ãããã¯ã¯å®å šã«æããã«ãããŠããŸããã§ããïŒã ãã ãããã®æ å ±ãããã¹ãŠãããã»ã©åçŽã§ã¯ãªããããšãç解ããé«ã¬ãã«ã®ãªããžã§ã¯ãã«é©çšãããäœã¬ãã«ã®é¢æ°ã䜿çšããåã«3åèãã䟡å€ãããããšãé¡ã£ãŠããŸãã ãããŠäžè¬çã«ãããã¯äŸ¡å€ããããŸããïŒ