欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言結(jié)構(gòu)體成員賦值的深拷貝與淺拷貝詳解

 更新時(shí)間:2022年09月30日 15:49:58   作者:編程小魚(yú)六六六  
C語(yǔ)言中的淺拷貝是指在拷貝過(guò)程中,對(duì)于指針型成員變量只拷貝指針本身,而不拷貝指針?biāo)赶虻哪繕?biāo),它按字節(jié)復(fù)制的。深拷貝除了拷貝其成員本身的值之外,還拷貝成員指向的動(dòng)態(tài)內(nèi)存區(qū)域內(nèi)容。本文將通過(guò)示例和大家詳細(xì)說(shuō)說(shuō)C語(yǔ)言的深拷貝與淺拷貝,希望對(duì)你有所幫助

淺拷貝

C語(yǔ)言中的淺拷貝是指在拷貝過(guò)程中,對(duì)于指針型成員變量只拷貝指針本身,而不拷貝指針?biāo)赶虻哪繕?biāo),它按字節(jié)復(fù)制的。我們分幾種情況舉例子來(lái)看一下。

結(jié)構(gòu)體中不存在指針成員變量時(shí)

代碼如下:

#include <stdio.h>
typedef struct {
    char name[64];
    int age;
}Member;
 
int main(){
    Member stu1 = { "LiMing", 18 };
    Member stu2;
    stu2 = stu1;
    printf("%s,%d\n", stu2.name, stu2.age);
    system("pause");
    return 0;
}

運(yùn)行如下:

結(jié)構(gòu)體中存在指針成員變量時(shí)

代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1, Member2;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
 
 Member2 = Member1;/*拷貝*/
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 printf("%s, %d\n", Member1.name, Member1.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 
 system("pause");
 return 0;
}

運(yùn)行如下:

從中我們看到,改變Member2的值,Member1的值也改變了,這說(shuō)明一片空間被兩個(gè)不同的子對(duì)象共享了,改變一個(gè)對(duì)象的值另外一個(gè)也會(huì)隨之改變。

我們改變Member2寫(xiě)法,申請(qǐng)內(nèi)存的代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
  
  Member Member2;
 Member2.name = malloc(sizeof(char) * 64);
 if (NULL == Member2.name)
 {
  printf("malloc failed\n");
 }
 memset(Member2.name, 0, 64);
 //strcpy(Member2.name, "LiMing");
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 Member1 = Member2;
 
 printf("%s, %d\n", Member2.name, Member2.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 if (NULL != Member2.name) {
  free(Member2.name);
  Member2.name = NULL;
 }
 system("pause");
 return 0;
}

運(yùn)行如下:

從中我們看到,當(dāng)數(shù)據(jù)成員中有指針時(shí),兩個(gè)類中的兩個(gè)指針將指向同一個(gè)地址,當(dāng)對(duì)象快結(jié)束時(shí),會(huì)調(diào)用兩次free函數(shù),此時(shí)Member2已經(jīng)是野指針(圖中有X的錯(cuò)誤標(biāo)志),這個(gè)野指針指向的內(nèi)存空間已經(jīng)被釋放掉,再次釋放會(huì)報(bào)異常錯(cuò)誤,要解決這個(gè)問(wèn)題就要涉及到深拷貝了。

深拷貝

深拷貝除了拷貝其成員本身的值之外,還拷貝成員指向的動(dòng)態(tài)內(nèi)存區(qū)域內(nèi)容,深拷貝會(huì)在堆內(nèi)存中另外申請(qǐng)空間來(lái)儲(chǔ)存數(shù)據(jù)。

解決的思路是在釋放掉被賦值指針變量的舊指向內(nèi)存時(shí),重新對(duì)其開(kāi)辟新內(nèi)存,這種情況下兩個(gè)結(jié)構(gòu)體中指針地址不同,但是指向的內(nèi)容是一致的。代碼如下:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
 
  Member Member2;
 Member2.name = malloc(sizeof(char) * 64);
 if (NULL == Member2.name)
 {
  printf("malloc failed\n");
 }
 memset(Member2.name, 0, 64);
 //strcpy(Member2.name, "LiMing");
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 if (Member1.name != NULL) {
  free(Member1.name);
  Member1.name = NULL;
 }
 Member1.name = malloc(strlen(Member2.name) + 1);
 strcpy(Member1.name, Member2.name);
 
 printf("%s, %d\n", Member1.name, Member1.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 if (NULL != Member2.name) {
  free(Member2.name);
  Member2.name = NULL;
 }
 system("pause");
 return 0;
}

運(yùn)行如下:

結(jié)論

使用C語(yǔ)言來(lái)說(shuō),深拷貝淺拷貝的概念我們不需要深究,在進(jìn)行結(jié)構(gòu)體拷貝的時(shí)候,結(jié)構(gòu)體成員是非指針的話,那么直接賦值是沒(méi)有任何問(wèn)題的,建議使用這種方式,避免淺拷貝這類不易發(fā)現(xiàn)的錯(cuò)誤產(chǎn)生。

如果成員有指針類型,我們就需要重寫(xiě)拷貝函數(shù),自己定義拷貝行為了,這一點(diǎn)我們需要尤為注意。

到此這篇關(guān)于C語(yǔ)言結(jié)構(gòu)體成員賦值的深拷貝與淺拷貝詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言深拷貝 淺拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言使用順序表實(shí)現(xiàn)電話本功能

    C語(yǔ)言使用順序表實(shí)現(xiàn)電話本功能

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言使用順序表實(shí)現(xiàn)電話本功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++實(shí)現(xiàn)遺傳算法

    C++實(shí)現(xiàn)遺傳算法

    這篇文章主要介紹了C++實(shí)現(xiàn)遺傳算法,以實(shí)例形式較為詳細(xì)的分析了遺傳算法的C++實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-12-12
  • C語(yǔ)言刷題判斷鏈表中是否有環(huán)題解

    C語(yǔ)言刷題判斷鏈表中是否有環(huán)題解

    這篇文章主要為大家介紹了C語(yǔ)言刷題判斷鏈表中是否有環(huán)題解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • do...while(0)的妙用詳細(xì)解析

    do...while(0)的妙用詳細(xì)解析

    do...while(0)消除goto語(yǔ)句;通常,如果在一個(gè)函數(shù)中開(kāi)始要分配一些資源,然后在中途執(zhí)行過(guò)程中如果遇到錯(cuò)誤則退出函數(shù),當(dāng)然,退出前先釋放資源
    2013-09-09
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 深入學(xué)習(xí)C語(yǔ)言中的函數(shù)指針和左右法則

    深入學(xué)習(xí)C語(yǔ)言中的函數(shù)指針和左右法則

    這篇文章主要介紹了深入學(xué)習(xí)C語(yǔ)言中的函數(shù)指針和左右法則,左右法則是一種常用的C指針聲明,需要的朋友可以參考下
    2015-08-08
  • C++ std::function的用法詳解

    C++ std::function的用法詳解

    這篇文章主要介紹了C++ std::function使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • Qt使用QJson模塊實(shí)現(xiàn)解析Json文件

    Qt使用QJson模塊實(shí)現(xiàn)解析Json文件

    在項(xiàng)目開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)遇到讀寫(xiě)Json文件的需求,掌握J(rèn)son文件的操作是基礎(chǔ)中的基礎(chǔ),下面我們就來(lái)看看如何使用QT內(nèi)置的QJson模塊解析Json文件吧
    2023-10-10
  • C語(yǔ)言的預(yù)處理介紹

    C語(yǔ)言的預(yù)處理介紹

    大家好,本篇文章主要講的是C語(yǔ)言的預(yù)處理介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • VS中動(dòng)態(tài)庫(kù)的創(chuàng)建和調(diào)用方式詳解

    VS中動(dòng)態(tài)庫(kù)的創(chuàng)建和調(diào)用方式詳解

    庫(kù)的存在形式本質(zhì)上來(lái)說(shuō)庫(kù)是一種可執(zhí)行代碼的二進(jìn)制,? 靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別主要是在鏈接階段處理庫(kù)的方式不同而區(qū)分的,本文介紹VS中動(dòng)態(tài)庫(kù)的創(chuàng)建和調(diào)用方式,感興趣的朋友一起看看吧
    2024-01-01

最新評(píng)論