ï»?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  åœ?C++ ä¸ï¼Œä½ 也许ç»å¸æ€‹Éç”?new å’?delete æ¥åЍæ€ç”³è¯·å’Œé‡Šæ”¾å†…å˜åQŒä½†ä½ 坿›¾æƒ³˜q‡ä»¥ä¸‹é—®é¢˜å‘¢åQ?/span>
  new å’?delete 是函数å—åQ?/span>
  new [] å’?delete [] åˆæ˜¯ä»€ä¹ˆï¼Ÿä»€ä¹ˆæ—¶å€™ç”¨å®ƒä»¬åQ?/span>
ã€€ã€€ä½ çŸ¥é?operator new å’?operator delete å—?
  ä¸ÞZ»€ä¹?new [] 出æ¥çš„æ•°¾l„有时å¯ä»¥ç”¨ delete 释放有时åˆä¸è¡Œï¼Ÿ
  �/span>
ã€€ã€€å¦‚æžœä½ å¯¹˜q™äº›é—®é¢˜éƒ½æœ‰ç–‘问的è¯åQŒä¸å¦¨çœ‹çœ‹æˆ‘˜q™ç¯‡æ–‡ç« ã€?/span>
  new �delete 到底是什么?
  如果扑ַ¥ä½œçš„åŒå¦çœ‹ä¸€äº›é¢è¯•的书,我相信都会é‡åˆ°è¿™æ ïLš„题:sizeof 䏿˜¯å‡½æ•°åQŒç„¶åŽä‹Då‡ÞZ¸€å †çš„ç†ç”±æ¥è¯æ˜?sizeof 䏿˜¯å‡½æ•°ã€‚在˜q™é‡ŒåQŒå’Œ sizeof ¾cÖM¼¼åQŒnew å’?delete ä¹Ÿä¸æ˜¯å‡½æ•ŽÍ¼Œå®ƒä»¬éƒ½æ˜¯ C++ 定义的关键å—åQŒé€šè¿‡ç‰¹å®šçš„è¯æ³•å¯ä»¥ç»„æˆè¡¨è¾‘ּ。和 sizeof ä¸åŒçš„æ˜¯åQŒsizeof 在编译时候就å¯ä»¥¼‹®å®šå…¶è¿”回å€û|¼Œnew å’?delete 背åŽçš„æœºåˆ¶åˆ™æ¯”è¾ƒå¤æ‚ã€?/span>
  ¾l§ç®‹å¾€ä¸‹ä¹‹å‰ï¼Œè¯·ä½ æƒÏxƒ³ä½ 认ä¸?new 应该è¦åšäº›ä»€ä¹ˆï¼Ÿä¹Ÿè®¸ä½ 第一å应是,new ä¸å°±å’?C è¯è¨€ä¸çš„ malloc å‡½æ•°ä¸€æ ·å˜›åQŒå°±ç”¨æ¥åЍæ€ç”³è¯ïL©ºé—´çš„ã€‚ä½ ½{”对了一åŠï¼Œçœ‹çœ‹ä¸‹é¢è¯å¥åQ?/span>
  string *ps = new string("hello world");
ã€€ã€€ä½ å°±å¯ä»¥çœ‹å‡º new å’?malloc ˜q˜æ˜¯æœ‰ç‚¹ä¸åŒçš„,malloc 甌™¯·å®Œç©ºé—´ä¹‹åŽä¸ä¼šå¯¹å†…嘘q›è¡Œå¿…è¦çš„åˆå§‹åŒ–åQŒè€?new å¯ä»¥ã€‚所ä»?new expression 背åŽè¦åšçš„äº‹æƒ…ä¸æ˜¯ä½ 惌™±¡çš„那么简å•。在我用实例æ¥è§£é‡?new 背åŽçš„æœºåˆ¶ä¹‹å‰ï¼Œä½ 需è¦çŸ¥é?operator new å’?operator delete 是什么玩æ„ã€?/span>
  operator new �operator delete
  ˜q™ä¸¤ä¸ªå…¶å®žæ˜¯ C++ è¯è¨€æ ‡å‡†åº“的库函敎ͼŒåŽŸåž‹åˆ†åˆ«å¦‚ä¸‹åQ?/span>
  void *operator new(size_t); //allocate an object
  void *operator delete(void *); //free an object
  void *operator new[](size_t); //allocate an array
  void *operator delete[](void *); //free an array
  åŽé¢ä¸¤ä¸ªä½ å¯ä»¥å…ˆä¸çœ‹åQŒåŽé¢å†ä»‹ç»ã€‚å‰é¢ä¸¤ä¸ªå‡æ˜?C++ æ ‡å‡†åº“å‡½æ•ŽÍ¼Œä½ å¯èƒ½ä¼šè§‰å¾—˜q™æ˜¯å‡½æ•°å—?请ä¸è¦æ€€ç–‘,˜q™å°±æ˜¯å‡½æ•ŽÍ¼C++ Primer ä¸€ä¹¦ä¸Šè¯´è¿™ä¸æ˜¯é‡è² new å’?delete 表达å¼ï¼ˆå¦?operator= ž®±æ˜¯é‡è² = æ“作½W¦ï¼‰åQŒå› ä¸?new å’?delete 是ä¸å…许é‡è²çš„ã€‚ä½†æˆ‘è¿˜æ²¡æžæ¸…楚ä¸ÞZ»€ä¹ˆè¦ç”?operator new å’?operator delete æ¥å‘½å,比较费解。我们åªè¦çŸ¥é“å®ƒä»¬çš„æ„æ€å°±å¯ä»¥äº†ï¼Œ˜q™ä¸¤ä¸ªå‡½æ•°å’Œ C è¯è¨€ä¸çš„ malloc å’?free 函数有点åƒäº†åQŒéƒ½æ˜¯ç”¨æ¥ç”³è¯·å’Œé‡Šæ”¾å†…å˜çš„,òq¶ä¸” operator new 甌™¯·å†…å˜ä¹‹åŽä¸å¯¹å†…嘘q›è¡Œåˆå§‹åŒ–,直接˜q”回甌™¯·å†…å˜çš„æŒ‡é’ˆã€?/span>
  我们å¯ä»¥ç›´æŽ¥åœ¨æˆ‘们的½E‹åºä¸ä‹Éç”¨è¿™å‡ ä¸ªå‡½æ•°ã€?/span>
  new å’?delete èƒŒåŽæœºåˆ¶
  知é“上é¢ä¸¤ä¸ªå‡½æ•°ä¹‹åŽåQŒæˆ‘们用一个实例æ¥è§£é‡Š new å’?delete 背åŽçš„æœºåˆÓž¼š
  我们ä¸ç”¨½Ž€å•çš„ C++ 内置¾cÕdž‹æ¥ä‹Dä¾‹ï¼Œä½¿ç”¨å¤æ‚一点的¾cȱ»åž‹ï¼Œå®šä¹‰ä¸€ä¸ªç±» AåQ?/span>
  class A
  {
  public:
  A(int v) : var(v)
  {
  fopen_s(&file, "test", "r");
  }
  ~A()
  {
  fclose(file);
  }
  private:
  int var;
  FILE *file;
  };
  很简å•,¾c?A 䏿œ‰ä¸¤ä¸ª¿U有æˆå‘˜åQŒæœ‰ä¸€ä¸ªæž„é€ å‡½æ•°å’Œä¸€ä¸ªæžæž„函敎ͼŒæž„é€ å‡½æ•îC¸åˆå§‹åŒ–ç§æœ‰å˜é‡?var ä»¥åŠæ‰“开一个文ä»Óž¼Œæžæž„å‡½æ•°å…³é—æ‰“开的文件ã€?/span>
  我们使用
  class *pA = new A(10);
  æ¥åˆ›å»ÞZ¸€ä¸ªç±»çš„对象,˜q”回其指é’?pA。如下图所½C?new 背åŽå®Œæˆçš„工作:
  ½Ž€å•æ€È»“一下:
  首先需è¦è°ƒç”¨ä¸Šé¢æåˆ°çš„ operator new æ ‡å‡†åº“å‡½æ•ŽÍ¼Œä¼ å…¥çš„å‚æ•îCØ“ class A 的大ž®ï¼Œ˜q™é‡Œä¸?8 个å—节,至于ä¸ÞZ»€ä¹ˆæ˜¯ 8 个å—èŠ‚ï¼Œä½ å¯ä»¥çœ‹çœ‹ã€Šæ·±å…?C++ 对象模型》一书,˜q™é‡Œä¸åšå¤šè§£é‡Šã€‚è¿™æ ·å‡½æ•°è¿”å›žçš„æ˜¯åˆ†é…内å˜çš„起始地å€åQŒè¿™é‡Œå‡è®¾æ˜¯ 0x007da290ã€?/span>
  上é¢åˆ†é…çš„å†…å˜æ˜¯æœªåˆå§‹åŒ–的,也是未类型化的,½W¬äºŒæ¥å°±åœ¨è¿™ä¸€å—原始的内å˜ä¸Šå¯¹¾cÕd¯¹è±¡è¿›è¡Œåˆå§‹åŒ–åQŒè°ƒç”¨çš„æ˜¯ç›¸åº”çš„æž„é€ å‡½æ•ŽÍ¼Œ˜q™é‡Œæ˜¯è°ƒç”?A:A(10); ˜q™ä¸ªå‡½æ•°åQŒä»Žå›¾ä¸ä¹Ÿå¯ä»¥çœ‹åˆ°å¯¹˜q™å—甌™¯·çš„内å˜è¿›è¡Œäº†åˆå§‹åŒ–,var=10, file æŒ‡å‘æ‰“开的文件ã€?/span>
  最åŽä¸€æ¥å°±æ˜¯è¿”回新分é…òq¶æž„é€ å¥½çš„å¯¹è±¡çš„æŒ‡é’ˆåQŒè¿™é‡?pA ž®±æŒ‡å?0x007da290 ˜q™å—内å˜åQŒpA çš„ç±»åž‹äØ“¾c?A 对象的指针ã€?/span>
  所有这三æ¥åQŒä½ 都å¯ä»¥é€šè¿‡å汇¾~–找到相应的汇编代ç åQŒåœ¨˜q™é‡Œæˆ‘å°±ä¸åˆ—å‡ÞZº†ã€?/span>
  好了åQŒé‚£ä¹?delete 都干了什么呢åQŸè¿˜æ˜¯æŽ¥ç€ä¸Šé¢çš„例å,如果˜q™æ—¶æƒ³é‡Šæ”¾æŽ‰ç”Œ™¯·çš„类的对象怎么办?当然我们å¯ä»¥ä½¿ç”¨ä¸‹é¢çš„è¯å¥æ¥å®ŒæˆåQ?/span>
  delete pA;
  delete 所åšçš„事情如下图所½Cºï¼š
  delete ž®±åšäº†ä¸¤ä»¶äº‹æƒ…:
  调用 pA 指å‘å¯¹è±¡çš„æžæž„函敎ͼŒå¯Òމ“开的文件进行关é—ã€?/span>
ã€€ã€€é€šè¿‡ä¸Šé¢æåˆ°çš„æ ‡å‡†åº“å‡½æ•° operator delete æ¥é‡Šæ”¾è¯¥å¯¹è±¡çš„内å˜ï¼Œä¼ å…¥å‡½æ•°çš„å‚æ•îCØ“ pA çš„å€û|¼Œä¹Ÿå°±æ˜?0x007d290ã€?/span>
  好了åQŒè§£é‡Šå®Œäº?new å’?delete èƒŒåŽæ‰€åšçš„äº‹æƒ…äº†ï¼Œæ˜¯ä¸æ˜¯è§‰å¾—也很简å•?ä¸å°±å¤šäº†ä¸€ä¸ªæž„é€ å‡½æ•°å’Œæžæž„函数的调用嘛ã€?/span>
  如何甌™¯·å’Œé‡Šæ”¾ä¸€ä¸ªæ•°¾l„?
  我们¾l常è¦ç”¨åˆ°åЍæ€åˆ†é…一个数¾l„,也许是这æ ïLš„åQ?/span>
  string *psa = new string[10]; //array of 10 empty strings
  int *pia = new int[10]; //array of 10 uninitialized ints
  上é¢åœ¨ç”³è¯·ä¸€ä¸ªæ•°¾l„时都用åˆîCº† new [] ˜q™ä¸ªè¡¨è¾¾å¼æ¥å®ŒæˆåQŒæŒ‰ç…§æˆ‘们上é¢è®²åˆ°çš„ new å’?delete 知识åQŒç¬¬ä¸€ä¸ªæ•°¾l„是 string ¾cÕdž‹åQŒåˆ†é…了ä¿å˜å¯¹è±¡çš„内å˜ç©ºé—´ä¹‹åŽï¼Œž®†è°ƒç”?string ¾cÕdž‹çš„é»˜è®¤æž„é€ å‡½æ•îC¾‹Æ¡åˆå§‹åŒ–æ•°ç»„ä¸æ¯ä¸ªå…ƒç´ ï¼›½W¬äºŒä¸ªæ˜¯ç”Œ™¯·å…ähœ‰å†…ç½®¾cÕdž‹çš„æ•°¾l„,分é…了å˜å‚?10 ä¸?int 对象的内å˜ç©ºé—ß_¼Œä½†åƈ没有åˆå§‹åŒ–ã€?/span>
  如果我们想释攄¡©ºé—´äº†åQŒå¯ä»¥ç”¨ä¸‹é¢ä¸¤æ¡è¯å¥åQ?/span>
  delete [] psa;
  delete [] pia;
  都用åˆ?delete [] 表达å¼ï¼Œæ³¨æ„˜q™åœ°æ–¹çš„ [] 一般情况下ä¸èƒ½æ¼æŽ‰åQ我们也å¯ä»¥æƒŒ™±¡˜q™ä¸¤ä¸ªè¯å¥åˆ†åˆ«å¹²äº†ä»€ä¹ˆï¼š½W¬ä¸€ä¸ªå¯¹ 10 ä¸?string å¯¹è±¡åˆ†åˆ«è°ƒç”¨æžæž„函数åQŒç„¶åŽå†é‡Šæ”¾æŽ‰äؓ对象分é…的所有内å˜ç©ºé—ß_¼›½W¬äºŒä¸ªå› 为是内置¾cÕdž‹ä¸å˜åœ¨æžæž„函敎ͼŒç›´æŽ¥é‡Šæ”¾ä¸?10 ä¸?int 型分é…的所有内å˜ç©ºé—´ã€?/span>
  ˜q™é‡Œå¯¹äºŽ½W¬ä¸€¿U情况就有一个问题了åQšæˆ‘ä»¬å¦‚ä½•çŸ¥é?psa 指å‘对象的数¾l„的大å°åQŸæ€Žä¹ˆçŸ¥é“è°ƒç”¨å‡ æ¬¡æžæž„函数åQ?/span>
  ˜q™ä¸ªé—®é¢˜ç›´æŽ¥å¯ÆD‡´æˆ‘们需è¦åœ¨ new [] 一个对象数¾l„æ—¶åQŒéœ€è¦ä¿å˜æ•°¾l„çš„¾l´åº¦åQŒC++ çš„åšæ³•æ˜¯åœ¨åˆ†é…æ•°¾l„空间时多分é…了 4 个å—节的大å°åQŒä¸“é—¨ä¿å˜æ•°¾l„的大å°åQŒåœ¨ delete [] æ—¶å°±å¯ä»¥å–出˜q™ä¸ªä¿å˜çš„æ•°åQŒå°±çŸ¥é“了需è¦è°ƒç”¨æžæž„函数多ž®‘次了ã€?/span>
  ˜q˜æ˜¯ç”¨å›¾æ¥è¯´æ˜Žæ¯”较清楚,我们定义了一个类 AåQŒä½†ä¸å…·ä½“æ˜q°ç±»çš„内容,˜q™ä¸ª¾cÖM¸æœ‰æ˜¾½Cºçš„æž„é€ å‡½æ•°ã€æžæž„函数ç‰ã€‚é‚£ä¹?当我们调ç”?/span>
  class A *pAa = new A[3];
  旉™œ€è¦åšçš„事情如下:
ã€€ã€€ä»Žè¿™ä¸ªå›¾ä¸æˆ‘们å¯ä»¥çœ‹åˆ°ç”³è¯äh—¶åœ¨æ•°¾l„对象的上题q˜å¤šåˆ†é…äº?4 个å—节用æ¥ä¿å˜æ•°¾l„的大å°åQŒä½†æ˜¯æœ€¾lˆè¿”回的是对象数¾l„的指针åQŒè€Œä¸æ˜¯æ‰€æœ‰åˆ†é…空间的起始地å€ã€?/span>
  ˜q™æ ·çš„è¯åQŒé‡Šæ”‘Ö°±å¾ˆç®€å•了åQ?/span>
  delete pAa;
  ˜q™é‡Œè¦æ³¨æ„的两点是:
ã€€ã€€è°ƒç”¨æžæž„函数的次数是从数¾l„对象指针å‰é¢çš„ 4 个å—节ä¸å–出åQ?/span>
ã€€ã€€ä¼ å…¥ operator delete[] å‡½æ•°çš„å‚æ•îC¸æ˜¯æ•°¾l„对象的指针 pAaåQŒè€Œæ˜¯ pAa çš„å€¼å‡ 4ã€?/span>
  ä¸ÞZ»€ä¹?new/delete ã€new []/delete[] è¦é…对ä‹É用?
  其实说了˜q™ä¹ˆå¤šï¼Œ˜q˜æ²¡åˆ°æˆ‘写这½‹‡æ–‡ç« 的最原始æ„图。从上é¢è§£é‡Šçš„ä½ åº”è¯¥æ‡‚äº† new/deleteã€new[]/delete[] 的工作原ç†äº†åQŒå› 为它们之间有差别åQŒæ‰€ä»¥éœ€è¦é…对ä‹É用。但ååé—®é¢˜ä¸æ˜¯˜q™ä¹ˆ½Ž€å•,˜q™ä¹Ÿæ˜¯æˆ‘é‡åˆ°çš„问题,如下˜q™æ®µä»£ç åQ?/span>
  int *pia = new int[10];
  delete []pia;
  ˜q™è‚¯å®šæ˜¯æ²¡é—®é¢˜çš„åQŒä½†å¦‚æžœæŠ?delete []pia; æ¢æˆ delete pia; çš„è¯åQŒä¼šå‡ºé—®é¢˜å—åQ?/span>
  ˜q™å°±æ¶‰åŠåˆîC¸Šé¢ä¸€èŠ‚æ²¡æåˆ°çš„é—®é¢˜äº†ã€‚ä¸Šé¢æˆ‘æåˆ°äº†åœ¨ new [] æ—¶å¤šåˆ†é… 4 个å—节的¾~˜ç”±åQŒå› ä¸ºæžæž„时需è¦çŸ¥é“æ•°¾l„的大å°åQŒä½†å¦‚æžœä¸è°ƒç”¨æžæž„函数呢åQˆå¦‚内置¾cÕdž‹åQŒè¿™é‡Œçš„ int 数组åQ‰ï¼Ÿæˆ‘们åœ?new [] 时就没必è¦å¤šåˆ†é…é‚?4 个å—节, delete [] 时直接到½W¬äºŒæ¥é‡Šæ”¾äØ“ int 数组分é…的空间。如果这里ä‹Éç”?delete pia;那么ž®†ä¼šè°ƒç”¨ operator delete 函数åQŒä¼ å…¥çš„å‚æ•°æ˜¯åˆ†é…给数组的è“v始地å€åQŒæ‰€åšçš„事情ž®±æ˜¯é‡Šæ”¾æŽ‰è¿™å—内å˜ç©ºé—´ã€‚ä¸å˜åœ¨é—®é¢˜çš„ã€?/span>
  ˜q™é‡Œè¯´çš„使用 new [] ç”?delete æ¥é‡Šæ”‘Ö¯¹è±¡çš„æå‰æ˜¯ï¼šå¯¹è±¡çš„类型是内置¾cÕdž‹æˆ–è€…æ˜¯æ— è‡ªå®šä¹‰çš„æžæž„函数的¾cȱ»åž‹ï¼
ã€€ã€€æˆ‘ä»¬çœ‹çœ‹å¦‚æžœæ˜¯å¸¦æœ‰è‡ªå®šä¹‰æžæž„函数的类¾cÕdž‹åQŒç”¨ new [] æ¥åˆ›å»ºç±»å¯¹è±¡æ•°ç»„åQŒè€Œç”¨ delete æ¥é‡Šæ”¾ä¼šå‘生什么?用上é¢çš„ä¾‹åæ¥è¯´æ˜Žï¼š
  class A *pAa = new class A[3];
  delete pAa;
  那么 delete pAa; åšäº†ä¸¤äšg事:
  调用一‹Æ?pAa 指å‘çš„å¯¹è±¡çš„æžæž„函数åQ?/span>
  调用 operator delete(pAa); 释放内å˜ã€?/span>
  昄¡„¶åQŒè¿™é‡Œåªå¯ÒŽ•°¾l„çš„½W¬ä¸€ä¸ªç±»å¯¹è±¡è°ƒç”¨äº†æžæž„函敎ͼŒåŽé¢çš„ä¸¤ä¸ªå¯¹è±¡å‡æ²¡è°ƒç”¨æžæž„函敎ͼŒå¦‚æžœ¾cÕd¯¹è±¡ä¸ç”Œ™¯·äº†å¤§é‡çš„内å˜éœ€è¦åœ¨æžæž„函数ä¸é‡Šæ”¾ï¼Œè€Œä½ å´åœ¨é”€æ¯æ•°¾l„对象时ž®‘è°ƒç”¨äº†æžæž„函数åQŒè¿™ä¼šé€ æˆå†…å˜æ³„æ¼ã€?/span>
  上é¢çš„é—®é¢˜ä½ å¦‚æžœè¯´æ²¡å…³ç³»çš„è¯åQŒé‚£ä¹ˆç¬¬äºŒç‚¹ž®±æ˜¯è‡´å‘½çš„了åQ直接释æ”?pAa 指å‘的内å˜ç©ºé—ß_¼Œ˜q™ä¸ªæ€ÀL˜¯ä¼šé€ æˆä¸¥é‡çš„æ®µé”™è¯¯åQŒç¨‹åºå¿…然会奔溃åQå› ä¸ºåˆ†é…çš„½Iºé—´çš„è“vå§‹åœ°å€æ˜?pAa 指å‘的地方å‡åŽ?4 个å—èŠ‚çš„åœ°æ–¹ã€‚ä½ åº”è¯¥ä¼ å…¥å‚æ•°è®¾äؓ那个地å€åQ?/span>