狠狠爱成人网_日韩一级在线_国产综合自拍_亚洲精品韩国_亚洲视频导航_麻豆成人在线播放_欧美jjzz_一区在线视频观看_美脚丝袜一区二区三区在线观看_欧美91视频

當前位置:系統之家 > 技術開發教程 > 詳細頁面

處理C++中動態內存分配引發的問題

處理C++中動態內存分配引發的問題

更新時間:2019-10-06 文章作者:未知 信息來源:網絡 閱讀次數:

  假設我們要開發一個String類,它可以方便地處理字符串數據。我們可以在類中聲明一個數組,考慮到有時候字符串極長,我們可以把數組大小設為200,但一般的情況下又不需要這么多的空間,這樣是浪費了內存。對了,我們可以使用new操作符,這樣是十分靈活的,但在類中就會出現許多意想不到的問題,本文就是針對這一現象而寫的。現在,我們先來開發一個Wrong類,從名稱上看出,它是一個不完善的類。的確,我們要刻意地使它出現各種各樣的問題,這樣才好對癥下藥。好了,我們開始吧!

  Wrong.h:

#ifndef WRONG_H_
#define WRONG_H_
class Wrong
{
private:
char * str; //存儲數據
int len; //字符串長度

public:
Wrong(const char * s); //構造函數
Wrong(); // 默認構造函數
~Wrong(); // 析構函數
friend ostream & operator<<(ostream & os,const Wrong& st);
};
#endif

Wrong.cpp:

#include <iostream>
#include <cstring>
#include "wrong.h"
using namespace std;
Wrong::Wrong(const char * s)
{
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);

}//拷貝數據

Wrong::Wrong()
{
len =0;
str = new char[len+1];
str[0]='\0';

}

Wrong::~Wrong()
{
cout<<"這個字符串將被刪除:"<<str<<'\n';//為了方便觀察結果,特留此行代碼。
delete [] str;
}

ostream & operator<<(ostream & os, const Wrong & st)
{
os << st.str;
return os;
}

test_right.cpp:

#include <iostream>
#include <stdlib.h>
#include "Wrong.h"
using namespace std;
int main()
{
Wrong temp("天極網");
cout<<temp<<'\n';
system("PAUSE");
return 0;
}

  運行結果:

  天極網

  請按任意鍵繼續. . .

  大家可以看到,以上程序十分正確,而且也是十分有用的。可是,我們不能被表面現象所迷惑!下面,請大家用test_wrong.cpp文件替換test_right.cpp文件進行編譯,看看結果。有的編譯器可能就是根本不能進行編譯!

  test_wrong.cpp:

#include <iostream>
#include <stdlib.h>
#include "Wrong.h"
using namespace std;
void show_right(const Wrong&);
void show_wrong(const Wrong);//注意,參數非引用,而是按值傳遞。
int main()
{
Wrong test1("第一個范例。");
Wrong test2("第二個范例。");
Wrong test3("第三個范例。");
Wrong test4("第四個范例。");
cout<<"下面分別輸入三個范例:\n";
cout<<test1<<endl;
cout<<test2<<endl;
cout<<test3<<endl;
Wrong* wrong1=new Wrong(test1);
cout<<*wrong1<<endl;
delete wrong1;
cout<<test1<<endl;//在Dev-cpp上沒有任何反應。
cout<<"使用正確的函數:"<<endl;
show_right(test2);
cout<<test2<<endl;
cout<<"使用錯誤的函數:"<<endl;
show_wrong(test2);
cout<<test2<<endl;//這一段代碼出現嚴重的錯誤!
Wrong wrong2(test3);
cout<<"wrong2: "<<wrong2<<endl;
Wrong wrong3;
wrong3=test4;
cout<<"wrong3: "<<wrong3<<endl;
cout<<"下面,程序結束,析構函數將被調用。"<<endl;
return 0;
}
void show_right(const Wrong& a)
{
cout<<a<<endl;
}
void show_wrong(const Wrong a)
{
cout<<a<<endl;
}


  運行結果:

  下面分別輸入三個范例:

  第一個范例。
  第二個范例。
  第三個范例。

  第一個范例。

  這個字符串將被刪除:第一個范例。

  使用正確的函數:
  
  第二個范例。
  第二個范例。

  使用錯誤的函數:
  第二個范例。

  這個字符串將被刪除:第二個范例。

  這個字符串將被刪除:?=
  ?=

  wrong2: 第三個范例。
  wrong3: 第四個范例。

  下面,程序結束,析構函數將被調用。

  這個字符串將被刪除:第四個范例。

  這個字符串將被刪除:第三個范例。

  這個字符串將被刪除:?=

  這個字符串將被刪除:x =

  這個字符串將被刪除:?=

  這個字符串將被刪除:

  現在,請大家自己試試運行結果,或許會更加慘不忍睹呢!下面,我為大家一一分析原因。

  首先,大家要知道,C++類有以下這些極為重要的函數:

  一:復制構造函數。

  二:賦值函數。

  我們先來講復制構造函數。什么是復制構造函數呢?比如,我們可以寫下這樣的代碼:Wrong test1(test2);這是進行初始化。我們知道,初始化對象要用構造函數。可這兒呢?按理說,應該有聲明為這樣的構造函數:Wrong(const Wrong &);可是,我們并沒有定義這個構造函數呀?答案是,C++提供了默認的復制構造函數,問題也就出在這兒。

  (1):什么時候會調用復制構造函數呢?(以Wrong類為例。)

  在我們提供這樣的代碼:Wrong test1(test2)時,它會被調用;當函數的參數列表為按值傳遞,也就是沒有用引用和指針作為類型時,如:void show_wrong(const Wrong),它會被調用。其實,還有一些情況,但在這兒就不列舉了。

  (2):它是什么樣的函數。

  它的作用就是把兩個類進行復制。拿Wrong類為例,C++提供的默認復制構造函數是這樣的:

Wrong(const Wrong& a)
{
str=a.str;
len=a.len;
}

  在平時,這樣并不會有任何的問題出現,但我們用了new操作符,涉及到了動態內存分配,我們就不得不談談淺復制和深復制了。以上的函數就是實行的淺復制,它只是復制了指針,而并沒有復制指針指向的數據,可謂一點兒用也沒有。打個比方吧!就像一個朋友讓你把一個程序通過網絡發給他,而你大大咧咧地把快捷方式發給了他,有什么用處呢?我們來具體談談:

  假如,A對象中存儲了這樣的字符串:“C++”。它的地址為2000。現在,我們把A對象賦給B對象:Wrong B=A。現在,A和B對象的str指針均指向2000地址。看似可以使用,但如果B對象的析構函數被調用時,則地址2000處的字符串“C++”已經被從內存中抹去,而A對象仍然指向地址2000。這時,如果我們寫下這樣的代碼:cout<<A<<endl;或是等待程序結束,A對象的析構函數被調用時,A對象的數據能否顯示出來呢?只會是亂碼。而且,程序還會這樣做:連續對地址2000處使用兩次delete操作符,這樣的后果是十分嚴重的!

  本例中,有這樣的代碼:

Wrong* wrong1=new Wrong(test1);
cout<<*wrong1<<endl;
delete wrong1;

  假設test1中str指向的地址為2000,而wrong中str指針同樣指向地址2000,我們刪除了2000處的數據,而test1對象呢?已經被破壞了。大家從運行結果上可以看到,我們使用cout<<test1時,一點反應也沒有。而在test1的析構函數被調用時,顯示是這樣:“這個字符串將被刪除:”。

  再看看這段代碼:

cout<<"使用錯誤的函數:"<<endl;
show_wrong(test2);
cout<<test2<<endl;//這一段代碼出現嚴重的錯誤!

  show_wrong函數的參數列表void show_wrong(const Wrong a)是按值傳遞的,所以,我們相當于執行了這樣的代碼:Wrong a=test2;函數執行完畢,由于生存周期的緣故,對象a被析構函數刪除,我們馬上就可以看到錯誤的顯示結果了:這個字符串將被刪除:?=。當然,test2也被破壞了。解決的辦法很簡單,當然是手工定義一個復制構造函數嘍!人力可以勝天!

Wrong::Wrong(const Wrong& a)
{
len=a.len;
str=new char(len+1);
strcpy(str,a.str);
}

  我們執行的是深復制。這個函數的功能是這樣的:假設對象A中的str指針指向地址2000,內容為“I am a C++ Boy!”。我們執行代碼Wrong B=A時,我們先開辟出一塊內存,假設為3000。我們用strcpy函數將地址2000的內容拷貝到地址3000中,再將對象B的str指針指向地址3000。這樣,就互不干擾了。

  大家把這個函數加入程序中,問題就解決了大半,但還沒有完全解決,問題在賦值函數上。我們的程序中有這樣的段代碼:

Wrong wrong3;
wrong3=test4;

  經過我前面的講解,大家應該也會對這段代碼進行尋根摸底:憑什么可以這樣做:wrong3=test4???原因是,C++為了用戶的方便,提供的這樣的一個操作符重載函數:operator=。所以,我們可以這樣做。大家應該猜得到,它同樣是執行了淺復制,出了同樣的毛病。比如,執行了這段代碼后,析構函數開始大展神威^_^。由于這些變量是后進先出的,所以最后的wrong3變量先被刪除:這個字符串將被刪除:第四個范例。很正常。最后,刪除到test4的時候,問題來了:這個字符串將被刪除:?=。原因我不用贅述了,只是這個賦值函數怎么寫,還有一點兒學問呢!大家請看:

  平時,我們可以寫這樣的代碼:x=y=z。(均為整型變量。)而在類對象中,我們同樣要這樣,因為這很方便。而對象A=B=C就是A.operator=(B.operator=(c))。而這個operator=函數的參數列表應該是:const Wrong& a,所以,大家不難推出,要實現這樣的功能,返回值也要是Wrong&,這樣才能實現A=B=C。我們先來寫寫看:

Wrong& Wrong::operator=(const Wrong& a)
{
delete [] str;//先刪除自身的數據
len=a.len;
str=new char[len+1];
strcpy(str,a.str);//此三行為進行拷貝
return *this;//返回自身的引用
}

  是不是這樣就行了呢?我們假如寫出了這種代碼:A=A,那么大家看看,豈不是把A對象的數據給刪除了嗎?這樣可謂引發一系列的錯誤。所以,我們還要檢查是否為自身賦值。只比較兩對象的數據是不行了,因為兩個對象的數據很有可能相同。我們應該比較地址。以下是完好的賦值函數:

Wrong& Wrong::operator=(const Wrong& a)
{
if(this==&a)
return *this;
delete [] str;
len=a.len;
str=new char[len+1];
strcpy(str,a.str);
return *this;
}

  把這些代碼加入程序,問題就完全解決,下面是運行結果:

  下面分別輸入三個范例:

  第一個范例
  第二個范例
  第三個范例

  第一個范例

  這個字符串將被刪除:第一個范例。

  第一個范例

   使用正確的函數:

  第二個范例。

  第二個范例。

   使用錯誤的函數:

  第二個范例。

  這個字符串將被刪除:第二個范例。

  第二個范例。

  wrong2: 第三個范例。
  wrong3: 第四個范例。

  下面,程序結束,析構函數將被調用。

  這個字符串將被刪除:第四個范例。
  這個字符串將被刪除:第三個范例。
  這個字符串將被刪除:第四個范例。
  這個字符串將被刪除:第三個范例。
  這個字符串將被刪除:第二個范例。
  這個字符串將被刪除:第一個范例。

  關于動態內存分配的問題就介紹到這兒,希望大家都能熱愛編程,熱愛C++!

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

狠狠爱成人网_日韩一级在线_国产综合自拍_亚洲精品韩国_亚洲视频导航_麻豆成人在线播放_欧美jjzz_一区在线视频观看_美脚丝袜一区二区三区在线观看_欧美91视频
一本一道波多野结衣一区二区| 欧美日韩免费一区二区三区视频| 欧美三级欧美一级| 久久综合久久综合久久综合| 亚洲美女区一区| 久久av中文字幕片| 91色porny蝌蚪| 免费成人在线观看| 国产69精品久久99不卡| 亚洲二区免费| 欧美另类变人与禽xxxxx| 国产精品剧情在线亚洲| 日本伊人色综合网| 欧美 日韩 国产 一区| 美女日韩在线中文字幕| 精品福利二区三区| 亚洲国产精品一区二区久久恐怖片 | 成人在线综合网| 最新国产乱人伦偷精品免费网站| 精品视频一区二区三区免费| 亚洲国产精品高清| 极品少妇一区二区三区精品视频 | 久久久美女毛片| 日韩精品三区四区| 午夜精品一区二区三区四区| 久久久久综合| 国产午夜精品一区二区 | 久久亚洲国产精品日日av夜夜| 精品久久国产字幕高潮| 婷婷中文字幕一区三区| 91麻豆国产精品久久| 色狠狠桃花综合| 国产精品天干天干在线综合| 久久精品噜噜噜成人av农村| 黄色在线一区| 日韩久久免费av| 日韩电影一区二区三区四区| 国内精品久久久久久久影视蜜臀| 欧美日韩国产三级| 亚洲一区二区美女| 91视视频在线直接观看在线看网页在线看| 色婷婷av一区二区三区软件| 国产精品久久久久影院色老大| 国产尤物一区二区| 欧美亚洲视频| 国产精品无码永久免费888| 国产自产高清不卡| 午夜宅男久久久| 国产精品麻豆99久久久久久| 国产精品一区二区久久精品爱涩| 亚洲免费一区二区| 欧美韩国一区二区| 国产成人免费在线观看| 一本一本大道香蕉久在线精品| 欧美国产精品一区二区三区| 国产传媒一区在线| 91高清在线观看| 一区二区三区.www| 国产在线一区二区三区四区 | 午夜精品一区二区三区四区| 欧美一二三区精品| 人人超碰91尤物精品国产| 亚洲理论在线| 亚洲国产精品激情在线观看| 亚洲精品在线三区| 久久99精品久久久久| 亚洲中字在线| 自拍偷拍亚洲欧美日韩| 99久久婷婷国产综合精品 | 中文字幕巨乱亚洲| gogo大胆日本视频一区| 欧美日韩日日摸| 青青草原综合久久大伊人精品| 国产一区二区黄色| 中文字幕日本不卡| 欧美日韩亚洲在线| 久久婷婷成人综合色| 国产99一区视频免费| 欧美日韩亚洲高清一区二区| 日韩福利电影在线观看| 亚洲一区高清| 一区二区三区不卡在线观看| 在线成人www免费观看视频| 久久精品欧美一区二区三区不卡| 成人性生交大片免费看在线播放| 欧美日韩国产系列| 久草中文综合在线| 在线免费观看日本欧美| 五月婷婷另类国产| 久久五月天婷婷| 亚洲成人一区二区在线观看| 中文久久精品| 一区二区三区中文字幕精品精品| 亚洲电影专区| 亚洲摸摸操操av| 亚洲狠狠婷婷| 一区二区三区在线看| 夜夜嗨av一区二区三区网站四季av| 中文字幕一区二区三区在线观看| 欧美99久久| 日本一区二区不卡视频| 欧美连裤袜在线视频| 欧美激情中文字幕一区二区| 欧美精品在线一区| 国产精品毛片无遮挡高清| 国产精品vip| 日韩毛片一二三区| 亚洲人体偷拍| 一区二区三区日本| 久久成人亚洲| 日韩国产精品大片| 欧美怡红院视频| 精品一区二区免费| 日韩天堂在线观看| eeuss鲁一区二区三区| 久久久影视传媒| 欧美三级午夜理伦三级中文幕| 欧美国产丝袜视频| 亚洲区国产区| 亚洲成人1区2区| 在线亚洲高清视频| 国产一区日韩二区欧美三区| 91精品国产综合久久久久久| 成人深夜视频在线观看| 久久久久久黄色| 日韩毛片高清在线播放| 亚洲精品1区2区| 亚洲h在线观看| 欧美午夜影院一区| 国产高清亚洲一区| 国产性天天综合网| 亚洲午夜高清视频| 亚洲国产中文字幕| 欧美性感一类影片在线播放| 国产成人精品在线看| 久久综合色婷婷| 精品不卡视频| 天天综合日日夜夜精品| 欧美色欧美亚洲另类二区| 懂色av一区二区三区免费看| 久久久久久久久岛国免费| 尹人成人综合网| 日韩精品欧美成人高清一区二区| 欧美日韩一区二区三区不卡| 成人免费观看视频| 国产精品美女久久福利网站| 国产伦精品一区| 精品中文字幕一区二区| 26uuu欧美| 99在线观看免费视频精品观看| 日韩高清在线一区| 日韩欧美国产麻豆| 一区在线播放| 免费人成在线不卡| 精品福利二区三区| 99国产精品私拍| 久久疯狂做爰流白浆xx| 久久亚洲精品小早川怜子| 亚洲区一区二| 精品无人码麻豆乱码1区2区| 久久精品在线免费观看| 国产亚洲欧美一区二区三区| 精品无人区卡一卡二卡三乱码免费卡| 久久综合九色综合97婷婷 | 欧美日韩一区二区三区免费看| 99久久精品国产观看| 一二三区精品视频| 在线综合+亚洲+欧美中文字幕| 欧美日本一区| 丝袜美腿亚洲一区二区图片| 精品日韩欧美一区二区| 日韩午夜激情| 国产毛片一区二区| 综合av第一页| 欧美日韩国产经典色站一区二区三区| 色综合天天天天做夜夜夜夜做| 亚洲一区在线观看免费观看电影高清| 欧美男生操女生| 亚洲国产免费| 国产精品亚洲午夜一区二区三区 | 中文字幕一区二区三区乱码在线| 色欧美片视频在线观看在线视频| 成人avav在线| 午夜欧美在线一二页| 2023国产精品自拍| 久久国产精品久久精品国产 | 国产日韩一区二区三区在线播放 | 亚洲成人免费在线观看| 欧美大片一区二区| 亚洲一区二区三区免费在线观看 | 精品日韩一区二区三区免费视频| 一本久久综合| 成人一级视频在线观看| 亚洲国产精品久久人人爱蜜臀| 欧美xingq一区二区| 久久av一区| 欧美精品尤物在线| 国内不卡的二区三区中文字幕| 日韩伦理免费电影| 欧美电视剧免费全集观看|