1 00:00:00,000 --> 00:00:03,792 [Mūzika spēlē ] 2 00:00:05,392 --> 00:00:07,881 DŪGS LOJS: Tātad šajā videoklipā mēs runāsim par to, kā dinamiski 3 00:00:07,881 --> 00:00:10,370 piešķirt atmiņu C. 4 00:00:10,370 --> 00:00:12,823 Tagad, kā atruna, ja neesat skatījies mūsu video par norādēm vai 5 00:00:12,823 --> 00:00:15,276 vispār neesat pazīstams ar norādes jēdzienu, jūs, iespējams, 6 00:00:15,276 --> 00:00:17,730 vēlēsities to apskatīt pirms šī. 7 00:00:17,730 --> 00:00:19,780 Šis video, dinamiskā atmiņas piešķiršana visparīgā nozīmē , darbojas 8 00:00:19,780 --> 00:00:21,830 īpaši ar rādītājiem. 9 00:00:21,830 --> 00:00:24,245 Tāpēc, pirms iedziļināties šajā konkrētajā videoklipā, vēlaties 10 00:00:24,245 --> 00:00:26,660 pārliecināties, vai esat apmierināts ar to. 11 00:00:26,660 --> 00:00:28,395 Sāksim bez turpmākas piepūles. 12 00:00:28,395 --> 00:00:30,770 Tagad mēs jau esam redzējuši, kā strādāt ar norādēm. 13 00:00:30,770 --> 00:00:33,120 Bet parasti mēs to darījām tikai kontekstā, lai norādītu 14 00:00:33,120 --> 00:00:35,470 norādesmainīgo, kuru mēs statiski deklarējam citam jau esošam 15 00:00:35,470 --> 00:00:37,820 mainīgajam. 16 00:00:37,820 --> 00:00:39,560 Iespējams, atceraties no mūsu video par rādītājiem, ka mums bija tāda 17 00:00:39,560 --> 00:00:41,300 līnija kā int x ir vienāds ar 5. 18 00:00:41,300 --> 00:00:45,029 Un tad mēs teiktu, ka int zvaigznīte px ir vienāds ar & x. 19 00:00:45,029 --> 00:00:46,299 Bet tas ir vienīgais veids, kā mēs esam redzējuši, kā strādāt ar 20 00:00:46,299 --> 00:00:47,570 norādēm. 21 00:00:47,570 --> 00:00:50,900 Un tā būtībā ir statiskās norādes lietošana. 22 00:00:50,900 --> 00:00:54,545 Lai strādātu ar norādēmstatiski, mums precīzi jāzina, cik daudz 23 00:00:54,545 --> 00:00:58,190 atmiņas mēs izmantosim programmas kompilēšanas brīdī. 24 00:00:58,190 --> 00:01:00,530 Tāpēc mēs neveidosim nekādu atmiņu darba gaitā 25 00:01:00,530 --> 00:01:04,647 Visa atmiņa, ko mēs izmantosim, jau ir iestatīta, kad mēs sākam. 26 00:01:04,647 --> 00:01:06,230 Tas rada sava veida problēmu, vai ne? 27 00:01:06,230 --> 00:01:09,590 Ko darīt, ja mēs nezinām, cik daudz atmiņas mums būs, kad sākam darbu? 28 00:01:09,590 --> 00:01:12,932 Varbūt jūs lūgsit lietotājam norādīt jums numuru, un viņš ģenerēs 29 00:01:12,932 --> 00:01:16,275 simts saistīto saraksta objektu. 30 00:01:16,275 --> 00:01:19,400 Tātad viņi radīs simtiem kaut ko, un jūs to nezināt. 31 00:01:19,400 --> 00:01:21,372 Vai varbūt viņi ģenerē 200 vai 400. 32 00:01:21,372 --> 00:01:24,068 Mēs nevarētu to iepriekš paredzēt, tāpēc mums ir jāizmanto dinamiskā 33 00:01:24,068 --> 00:01:26,764 atmiņas piešķiršana, lai programmā iegūtu jaunu atmiņu, kamēr 34 00:01:26,764 --> 00:01:29,460 programma jau darbojas. 35 00:01:29,460 --> 00:01:32,210 Un tas ir nedaudz savādāk nekā jebkas, ko esam redzējuši iepriekš. 36 00:01:32,210 --> 00:01:33,680 Mēs to varam izdarīt, piešķirot atmiņu no kaut kā, kas tiek saukts 37 00:01:33,680 --> 00:01:35,150 heap - kaudzīte. 38 00:01:35,150 --> 00:01:37,121 Kaudzīte ir milzīgs atmiņu krājums. 39 00:01:37,121 --> 00:01:39,225 Un līdz šim vienīgais mums pazīstamais atmiņas kopums tiek saukts par 40 00:01:39,225 --> 00:01:41,330 kaudzi . 41 00:01:41,330 --> 00:01:44,470 Bet dinamiski piešķirtā atmiņa nāk no kaudzītes , un statiski 42 00:01:44,470 --> 00:01:47,610 piešķirtā atmiņa — jebkas, kam parasti piešķirat nosaukumu, piemēram, 43 00:01:47,610 --> 00:01:50,750 mainīgā nosaukums — tiks iestatīta kaudzē. 44 00:01:50,750 --> 00:01:53,106 Un viss, ko izveidojat dinamiski, kamēr programma darbojas, nāks no 45 00:01:53,106 --> 00:01:55,462 kaudzītes . 46 00:01:55,462 --> 00:01:57,981 Bet, kā redzams no šīs diagrammas, kaudze un kaudzīte patiesībā ir 47 00:01:57,981 --> 00:02:00,500 viena un tā pati liela atmiņas daļa. 48 00:02:00,500 --> 00:02:02,855 Tas ir tā, ka kaudze, ko mēs piešķiram no apakšas uz augšu, parasti 49 00:02:02,855 --> 00:02:05,210 ir, lai to vizualizētu. 50 00:02:05,210 --> 00:02:08,712 Tādējādi kaudze atmiņas adreses būs nedaudz mazākas, un kaudzītes 51 00:02:08,712 --> 00:02:12,214 skaitļi būs lielāki, un tas tiks piešķirts lejup. 52 00:02:12,214 --> 00:02:14,484 Tātad tas patiešām ir viens milzīgs atmiņas kopums, taču mēs to 53 00:02:14,484 --> 00:02:16,754 saucam par divām dažādām lietām atkarībā no tā, kā tā tiek izmantota. 54 00:02:16,754 --> 00:02:20,434 Statiski deklarētās atmiņas kaudze palielinās un dinamiski piešķirtās 55 00:02:20,434 --> 00:02:24,115 atmiņas kaudzīte samazinās. 56 00:02:24,115 --> 00:02:26,240 Kā mēs tiekam pie šīs dinamiski piešķirtās atmiņas? 57 00:02:26,240 --> 00:02:28,130 Kā mēs varam piekļūt kaudzītes atmiņai? 58 00:02:28,130 --> 00:02:31,400 Mums ir jāizmanto jauna funkcija, ko sauc par malloc. 59 00:02:31,400 --> 00:02:34,520 Malloc var iegūt par mārciņu, ieskaitot standarta lib.h, stdlib.h. 60 00:02:34,520 --> 00:02:35,756 Un vienīgais arguments, kas jums ir jānodod malloc, ir tas, cik baitu 61 00:02:35,756 --> 00:02:36,992 atmiņas vēlaties. 62 00:02:42,060 --> 00:02:44,420 Tātad, ja vēlaties veselu skaitli, sakiet malloc 4. 63 00:02:44,420 --> 00:02:46,460 Ja vēlaties rakstzīmi , malloc 1. 64 00:02:46,460 --> 00:02:48,960 Ja vēlaties dubultot, malloc 8 utt. 65 00:02:48,960 --> 00:02:51,770 Un jūs varat rīkoties daudz sarežģītāk, kā mēs drīz redzēsim. 66 00:02:51,770 --> 00:02:54,670 Malloc mēģinās atrast kaudzītē tādu atmiņas apjomu , kādu jūs 67 00:02:54,670 --> 00:02:57,570 prasījāt. 68 00:02:57,570 --> 00:02:59,162 Tātad tas mēģinās atrast, piemēram, astoņus blakus esošos atmiņas 69 00:02:59,162 --> 00:03:00,755 baitus. 70 00:03:00,755 --> 00:03:03,192 Ja mēs piešķiram dubultu, tas mēģinās atrast astoņus blakus esošos 71 00:03:03,192 --> 00:03:05,630 atmiņas baitus no kaudzītes . 72 00:03:05,630 --> 00:03:07,746 Un tas, ko tas darīs, ir tas, ka tas atgriezīs jums norādi uz šo 73 00:03:07,746 --> 00:03:09,862 atmiņu. 74 00:03:09,862 --> 00:03:13,188 Tātad vienīgais veids, kā mēs varēsim piekļūt dinamiski piešķirtajai 75 00:03:13,188 --> 00:03:16,514 atmiņai vai to izmantot, ir novirzot no malloc iegūto norādi. 76 00:03:16,514 --> 00:03:20,300 Un tāpēc pirms došanās uz priekšu ir svarīgi saprast norādes. 77 00:03:20,300 --> 00:03:23,090 Tagad ir iespējams, ka malloc faktiski nevarēs atjaunot atmiņu, un 78 00:03:23,090 --> 00:03:25,880 tādā gadījumā tas atgriezīsies pie nulles. 79 00:03:25,880 --> 00:03:28,992 Un tāpēc viens no pirmajiem noteikumiem, kas jāatceras par dinamiski 80 00:03:28,992 --> 00:03:32,105 piešķirto atmiņu, ir vienmēr pārbaudīt nulli pēc malloc. 81 00:03:32,105 --> 00:03:33,230 Tagad, kāpēc tas varētu notikt? 82 00:03:33,230 --> 00:03:34,280 Varbūt jums ir beigusies atmiņa. 83 00:03:34,280 --> 00:03:36,935 Kaudze un kaudzīte ir tikko pilnībā beigušās, vai arī ir notikusi 84 00:03:36,935 --> 00:03:39,590 kāda katastrofāla kļūme, ko nevaram paredzēt. 85 00:03:39,590 --> 00:03:41,626 Bet jebkurā gadījumā, ja no mūsu norādes video atceraties, ka norādes 86 00:03:41,626 --> 00:03:43,662 tiek atceltas uz nulles rādītāju, tās ir sliktas ziņas. 87 00:03:43,662 --> 00:03:46,176 Tāpēc pirmā lieta, ko vēlaties darīt — protams, pēc malloc — ir 88 00:03:46,176 --> 00:03:48,690 jāpārbauda, vai jūs nesaņēmāt nulli. 89 00:03:48,690 --> 00:03:52,020 Un, ja jūs to izdarījāt, jums būs jāpārtrauc programma, jo kaut kas 90 00:03:52,020 --> 00:03:55,350 ir nogājis greizi un jūs nevarat turpināt to, kas jums ir pašlaik. 91 00:03:55,350 --> 00:03:57,595 Tātad, ja mēs vēlamies vienkārši iegūt veselu skaitli, statiski 92 00:03:57,595 --> 00:03:59,840 deklarējiet to, mēs varam vienkārši pateikt int x. 93 00:03:59,840 --> 00:04:02,600 Tādējādi kaudzē tiks izveidots mainīgais ar nosaukumu x, kuram pēc 94 00:04:02,600 --> 00:04:05,360 tam varēsim piešķirt jebkuru vērtību, kas mums patīk. 95 00:04:05,360 --> 00:04:08,605 Ja vēlaties dinamiski piešķirt veselu skaitli, mēs sakām: int star px 96 00:04:08,605 --> 00:04:11,851 ir vienāds ar malloc 4. 97 00:04:11,851 --> 00:04:14,185 Un iemesls, kāpēc mēs šeit sakām četrus, ir tāpēc, ka veselā skaitlī 98 00:04:14,185 --> 00:04:16,519 ir četri baiti. 99 00:04:16,519 --> 00:04:18,769 Es viegli būtu varējis izmantot arī operatora izmēru, kas ir pieejams 100 00:04:18,769 --> 00:04:21,019 C valodā. 101 00:04:21,019 --> 00:04:23,790 Būtībā jūs to nododat tipam  — tāpēc tas ir nedaudz savādāk. 102 00:04:23,790 --> 00:04:25,760 Parasti ar funkcijām tiek ievadīts mainīgais. 103 00:04:25,760 --> 00:04:29,775 Izmantojot malloc, jūs ievadāt vai ar sizeof, drīzāk ievadāt tipu, un 104 00:04:29,775 --> 00:04:33,790 tas atgriezīs, cik baitu šis tips aizņem sistēmā. 105 00:04:33,790 --> 00:04:36,567 Tātad int zvaigznīte px ir vienāds ar malloc lielums int vai int 106 00:04:36,567 --> 00:04:39,345 zvaigznīte ps ir vienāds ar malloc 4 būtībā nozīmē, ka malloc 107 00:04:39,345 --> 00:04:42,122 gatavojas atrast jums četrus baitus atmiņas, kas atrodas blakus viens 108 00:04:42,122 --> 00:04:44,900 otram uz kaudzītes . 109 00:04:44,900 --> 00:04:48,749 Un malloc atgriezīs jums norādiuz šo atmiņu, ko sauc par px. 110 00:04:48,749 --> 00:04:51,267 Un tad mēs varētu neizmantot šo norādi, kā mēs redzējām norādes 111 00:04:51,267 --> 00:04:53,785 video, lai ar to manipulētu, ievietotu tajā vērtību un darītu ar to 112 00:04:53,785 --> 00:04:56,304 visu, ko vēlamies. 113 00:04:56,304 --> 00:04:57,720 Apskatīsim vēl vienu piemēru. 114 00:04:57,720 --> 00:05:00,120 Varbūt mēs vēlamies iegūt veselu skaitli no lietotāja. 115 00:05:00,120 --> 00:05:01,735 Tāpēc atcerieties, ka CS50 mums ir funkcija get_int, ko varam 116 00:05:01,735 --> 00:05:03,350 izmantot. 117 00:05:03,350 --> 00:05:04,830 Int x ir vienāds ar get_int. 118 00:05:04,830 --> 00:05:08,020 Mēs būtībā prasām lietotājam kādu veselu skaitļu vērtību. 119 00:05:08,020 --> 00:05:12,160 Un tas mums dos kādu skaitli, cerams, šajā piemērā pozitīvu skaitli. 120 00:05:12,160 --> 00:05:14,155 Pieņemsim, ka es vēlos paziņot par masīvu, kurā ir tik daudz peldošu 121 00:05:14,155 --> 00:05:16,150 elementu. 122 00:05:16,150 --> 00:05:19,060 Es to varu izdarīt, pasakot float stack_array un pēc tam 123 00:05:19,060 --> 00:05:21,970 kvadrātiekavās — kas atkal norāda masīva lielumu — x. 124 00:05:21,970 --> 00:05:23,875 Tas ir likumīgi C 99 un C 11. 125 00:05:23,875 --> 00:05:27,730 Ja izmantojat ļoti vecu C versiju, tas faktiski nebija atļauts. 126 00:05:27,730 --> 00:05:28,570 Bet jūs varat to izdarīt. 127 00:05:28,570 --> 00:05:32,665 Būtībā mēs varam iegūt mainīga izmēra masīvu kaudzē , ko mēs šeit 128 00:05:32,665 --> 00:05:36,760 darām, jo mēs iepriekš nezinām, cik liels tas būs. 129 00:05:36,760 --> 00:05:37,820 Mēs to tikai saņemam no lietotāja. 130 00:05:37,820 --> 00:05:41,230 Bet šādā veidā mēs varētu deklarēt pludiņu masīvu kaudzē, kur vienumu 131 00:05:41,230 --> 00:05:44,640 skaits šajā masīvā ir numurs, ko lietotājs mums tikko iedeva. 132 00:05:44,640 --> 00:05:48,160 Un es varu arī dinamiski piešķirt pludiņu masīvu kaudzītē — nevis 133 00:05:48,160 --> 00:05:51,680 kaudzē , atcerieties, jo šoreiz mēs dinamiski piešķiram atmiņu. 134 00:05:51,680 --> 00:05:52,810 Float star heap_array. 135 00:05:52,810 --> 00:05:55,740 Tā ir mana norāde uz atmiņu, ko es iegūstu. 136 00:05:55,740 --> 00:05:58,390 Un es gribu malloc x reizes lielāku par peldošu vērtību. 137 00:05:58,390 --> 00:06:01,165 Tātad, ja es vēlos iegūt 50 pludiņus, man vajag 50 reizes lielāku par 138 00:06:01,165 --> 00:06:03,940 peldošu vērtību, tātad 50 reizes 4. 139 00:06:03,940 --> 00:06:06,310 Varbūt es gribu 100, tāpēc tas būtu 100 reiz četri. 140 00:06:06,310 --> 00:06:08,435 Tāpēc mēs tur veicam reizināšanu. 141 00:06:08,435 --> 00:06:12,508 Un malloc atgriežmums vienu milzīgu šāda izmēra atmiņas bloku, ko mēs 142 00:06:12,508 --> 00:06:16,581 pēc tam varam vienkārši uzskatīt par jebkuru citu masīvu. 143 00:06:16,581 --> 00:06:19,717 Tomēr mums ir jācīnās ar dinamiski piešķirto atmiņu, un tas ir kaut 144 00:06:19,717 --> 00:06:22,853 kas tāds, ko mēs vēl neesam redzējuši, un tas ir, ka tā netiek 145 00:06:22,853 --> 00:06:25,990 atgriezta atpakaļ sistēmā, kad esat pabeidzis. 146 00:06:25,990 --> 00:06:29,140 Tātad, ja vēl neesat redzējis mūsu videoklipu par izsaukumā kaudzēm 147 00:06:29,140 --> 00:06:32,290 vai kaudzes rāmjiem, iespējams, tas jums vēl nav zināms. 148 00:06:32,290 --> 00:06:35,590 Bet parasti, kad funkcija beidz darboties, visa atmiņa, kas tika 149 00:06:35,590 --> 00:06:38,890 izveidota šīs funkcijas pastāvēšanai , tiek iznīcināta un tiek 150 00:06:38,890 --> 00:06:42,190 atbrīvota atpakaļ sistēmā, lai to izmantotu kaut kur citur. 151 00:06:42,190 --> 00:06:44,155 Tātad cits funkcijas izsaukums, kas varētu parādīties, var izmantot 152 00:06:44,155 --> 00:06:46,120 to pašu atmiņas bitu iepriekš. 153 00:06:46,120 --> 00:06:47,495 Tas ir diezgan ērti, vai ne? 154 00:06:47,495 --> 00:06:50,710 Šī sistēma pastāvīgi tiek pārstrādāta, kur vien iespējams. 155 00:06:50,710 --> 00:06:53,715 Bet, kad jūs sakāt sistēmai, es gribu atmiņas bloku, sistēma neko par 156 00:06:53,715 --> 00:06:56,720 to neuzņemsies. 157 00:06:56,720 --> 00:06:59,723 Tā nepieņems, ka nav redzējusi, ka jūs ar to izsaucāt50 līniju garumā 158 00:06:59,723 --> 00:07:02,726 vai citādi un tas tikai dinamiski atbrīvos to vai atgriezīs to 159 00:07:02,726 --> 00:07:05,729 atpakaļ sistēmā. 160 00:07:05,729 --> 00:07:08,235 Un, ja neizdodas atgriezt pietiekami daudz atmiņas sistēmā, tas tiek 161 00:07:08,235 --> 00:07:10,741 saukts par atmiņas noplūdi. 162 00:07:10,741 --> 00:07:12,630 Un atmiņas noplūdes patiešām nav labas, jo tās patiešām var palēnināt 163 00:07:12,630 --> 00:07:14,520 jūsu sistēmu. 164 00:07:14,520 --> 00:07:17,831 Un patiesībā ir dažas pārlūkprogrammas, kas paliks bez nosaukuma un 165 00:07:17,831 --> 00:07:21,142 ir savā ziņā bēdīgi slavenas ar to, ka neatbrīvo atmiņu vai neatbrīvo 166 00:07:21,142 --> 00:07:24,454 atmiņu atpakaļ sistēmā, kad tas ir paveikts. 167 00:07:24,454 --> 00:07:27,298 Un tas patiešām var izraisīt jūsu datora palēnināšanos, jo šī 168 00:07:27,298 --> 00:07:30,142 pārlūkprogramma pamatā aizņem daudz atmiņas, un citas jūsu datorā 169 00:07:30,142 --> 00:07:32,986 esošās programmas nevar to izmantot, jo pārlūkprogramma to ir 170 00:07:32,986 --> 00:07:35,830 piešķīrusi un teikusi : nē, šī ir mana. 171 00:07:35,830 --> 00:07:36,810 Man to vajag. 172 00:07:36,810 --> 00:07:40,246 Taču tā nekad to neizlaiž atpakaļ, lai to varētu koplietot sistēmā. 173 00:07:40,246 --> 00:07:42,744 Tāpēc, ja pārlūkprogrammu atstājat atvērtu vairākas dienas vai dažas 174 00:07:42,744 --> 00:07:45,242 pārlūkprogrammas ir atvērtas vairākas dienas vai nedēļas, varat 175 00:07:45,242 --> 00:07:47,740 pamanīt, ka datora darbība sāk palēnināties. 176 00:07:47,740 --> 00:07:50,040 Tagad noteikums ir tāds, kā jau minēju iepriekš, kad esat pabeidzis 177 00:07:50,040 --> 00:07:52,340 darbu ar dinamiski piešķirto atmiņu, viss, kas jums jādara, ir to 178 00:07:52,340 --> 00:07:54,640 atbrīvot. 179 00:07:54,640 --> 00:07:57,880 Un freeir vēl viena funkcija, kas ir pieejama standarta lib.h. 180 00:07:57,880 --> 00:08:00,610 Un būtībā tas, ko norādījāt uz free, ir norādeuz jebkuru atmiņu, kuru 181 00:08:00,610 --> 00:08:03,340 iepriekš esat dinamiski piešķīrusi. 182 00:08:03,340 --> 00:08:05,830 Un būtībā tas ir tikai paziņojums sistēmai, es esmu pabeidzis. 183 00:08:05,830 --> 00:08:08,029 Varat izmantot šo atmiņu jebkuram nolūkam. 184 00:08:08,029 --> 00:08:11,129 Tātad, šeit ir vēl viens piemērs, pieņemsim, ka mēs vēlamies izveidot 185 00:08:11,129 --> 00:08:14,230 50 rakstzīmju garu masīvu — tātad būtībā lielu virkni. 186 00:08:14,230 --> 00:08:15,420 Mēs to sauksim par vārdu. 187 00:08:15,420 --> 00:08:16,682 Mēs to dinamiski sadalām. 188 00:08:16,682 --> 00:08:18,140 Tad mēs ar to darām dažas lietas. 189 00:08:18,140 --> 00:08:20,752 Varbūt mēs bijām kādas funkcijas vidū. 190 00:08:20,752 --> 00:08:22,210 Ziniet, mēs mainām tā vērtību. 191 00:08:22,210 --> 00:08:23,230 Mēs piešķiram jaunas rakstzīmes . 192 00:08:23,230 --> 00:08:24,730 Mēs, piemēram, to izdrukājam. 193 00:08:24,730 --> 00:08:26,350 Un tad mēs nolemjam, ka esam to pabeiguši. 194 00:08:26,350 --> 00:08:28,099 Kā to atgriezt sistēmā? 195 00:08:28,099 --> 00:08:29,140 Mums tas vienkārši jāatbrīvo. 196 00:08:29,140 --> 00:08:30,517 Tātad mēs atbrīvojām word. 197 00:08:30,517 --> 00:08:32,350 Word ir norādeuz šo atmiņas bloku. 198 00:08:32,350 --> 00:08:34,645 Tā ir lieta, ko mēs vēlamies atbrīvot. 199 00:08:34,645 --> 00:08:37,232 Tātad malloc un free ir trīs pamatnoteikumi, kurus ir patiešām 200 00:08:37,232 --> 00:08:39,820 svarīgi internalizēt. 201 00:08:39,820 --> 00:08:42,235 Pirmkārt, viss, ko izmantojat malloc, ir jāatbrīvo, pirms programma 202 00:08:42,235 --> 00:08:44,650 beidz darboties. 203 00:08:44,650 --> 00:08:47,373 Tagad, protams, ja jūsu programma faktiski beidz darboties, kad tā ir 204 00:08:47,373 --> 00:08:50,096 pilnībā pabeigta, piemēram, kad esat atgriezis nulli no main, tā tiks 205 00:08:50,096 --> 00:08:52,820 atbrīvota. 206 00:08:52,820 --> 00:08:55,855 Bet tā ir laba prakse, lai pārliecinātos, ka viss, ko piešķirat jums, 207 00:08:55,855 --> 00:08:58,890 jūs atvrīvojāt , skaidri izsaucot free funkciju, nevis tikai 208 00:08:58,890 --> 00:09:01,925 paļauties uz to, ka sistēma to izdarīs, kad programma ir pilnībā 209 00:09:01,925 --> 00:09:04,960 pabeigta. 210 00:09:04,960 --> 00:09:08,260 Tātad viss, kad jūs izmantojat malloc, jums ir jāatbrīvo. 211 00:09:08,260 --> 00:09:10,108 Otrais noteikums — tikai tās lietas, kuras jūs darāt, izmantojot 212 00:09:10,108 --> 00:09:11,957 malloc ir tās, kuras jums vajadzētu atbrīvot. 213 00:09:11,957 --> 00:09:14,790 Tātad, ja jūs statiski deklarējāt mainīgo, jūs nevēlaties to atbrīvot. 214 00:09:14,790 --> 00:09:17,165 Sistēma parūpēsies par visas statiski deklarētās atmiņas atbrīvošanu 215 00:09:17,165 --> 00:09:19,540 jūsu vietā. 216 00:09:19,540 --> 00:09:22,255 Tā ir tikai dinamiski piešķirta atmiņa — tikai atmiņa, kad jūs 217 00:09:22,255 --> 00:09:24,970 izmantojat malloc , ir lietas, kuras jums vajadzētu atbrīvot. 218 00:09:24,970 --> 00:09:27,598 Un pēc tam noteikti neatbrīvojiet vienu un to pašu atmiņas bloku 219 00:09:27,598 --> 00:09:30,226 vairāk nekā vienu reizi, jo tas var radīt dubultas atbrīvošanas 220 00:09:30,226 --> 00:09:32,854 problēmu, un jums ir sava veida apgriezta atmiņas noplūde, piemēram, 221 00:09:32,854 --> 00:09:35,482 atmiņas plūsma vai kaut kas tamlīdzīgs, kad jūs mānījāt sistēmu, 222 00:09:35,482 --> 00:09:38,110 domājot, ka jums ir vairāk atmiņas nekā jums patiesībā ir. 223 00:09:38,110 --> 00:09:40,443 Tas nav tāds, ko jūs patiesībā vēlaties darīt. 224 00:09:40,443 --> 00:09:41,616 Tāpēc atcerieties, ka viss, kas jums jādara, izmantojot malloc ir 225 00:09:41,616 --> 00:09:42,790 jāatbrīvo. 226 00:09:42,790 --> 00:09:43,915 Tikai tās lietas, ko jūs darāt, izmantojot malloc, jums vajadzētu 227 00:09:43,915 --> 00:09:45,040 atbrīvot. 228 00:09:45,040 --> 00:09:48,877 Un neatbrīvojiet neko vairāk kā vienu reizi. 229 00:09:48,877 --> 00:09:52,738 Noslēdzam šo videoklipu, apskatot pāris koda rindiņas un vizuālu 230 00:09:52,738 --> 00:09:56,600 piemēru, lai parādītu, kas tieši notiek, kad to darām. 231 00:09:56,600 --> 00:09:59,290 Tātad vispirms statiski deklarēsim veselu skaitli, ko sauc par m. 232 00:09:59,290 --> 00:10:01,081 Un tāpēc tas izskatītos apmēram šādi. 233 00:10:01,081 --> 00:10:03,655 Esmu nokrāsojis lodziņu zaļu, jo manā galvā veseli skaitļi vienmēr ir 234 00:10:03,655 --> 00:10:06,230 zaļos lodziņos . 235 00:10:06,230 --> 00:10:09,400 Un uz lodziņa esmu uzrakstījis marķējumu m. 236 00:10:09,400 --> 00:10:11,570 Tad es teikšu int zvaigznīte a. 237 00:10:11,570 --> 00:10:15,950 Tāpēc šeit es statiski deklarēju norādi, ko sauc par a. 238 00:10:15,950 --> 00:10:18,805 Tāpēc atcerieties, ka man patīk domāt, ka tā ir int zvaigznīte , 239 00:10:18,805 --> 00:10:21,660 tātad tā ir int līdzīga, tāpēc tā būs zaļa. 240 00:10:21,660 --> 00:10:22,610 Tas ir zaļgans lodziņš. . 241 00:10:22,610 --> 00:10:24,710 Tas nav zaļš lodziņš, jo tas ir paredzēts ints. 242 00:10:24,710 --> 00:10:26,420 Bet iekšējās zvaigznītes ir sava veida zaļas. 243 00:10:26,420 --> 00:10:27,410 Tās attiecas uz ints. 244 00:10:27,410 --> 00:10:30,570 Tātad šie ir citi lodziņi , un šo sauc par a. 245 00:10:30,570 --> 00:10:37,050 Tad es varu teikt, ka int star b ir vienāds ar malloc sizeof int. 246 00:10:37,050 --> 00:10:38,370 Tātad, kas šeit notiks? 247 00:10:38,370 --> 00:10:41,244 Nu, man būs kaut kas, ko sauc par b, kam es dodu vārdu. 248 00:10:41,244 --> 00:10:43,460 Tātad tas būs gaiši zaļgans lodziņš. 249 00:10:43,460 --> 00:10:47,480 Un es lūdzu malloc dinamiski piešķirt man vienu int vērtu vietu. 250 00:10:47,480 --> 00:10:51,020 Un tas, kas patiesībā notika vizuāli, ir šāds. 251 00:10:51,020 --> 00:10:54,230 Ņemiet vērā, ka veselajam skaitlim es nenosaucu nosaukumu. 252 00:10:54,230 --> 00:10:55,910 Man tam nav vārda. 253 00:10:55,910 --> 00:10:57,670 Tas ir viens no veidiem, kā parasti es zinu, ka man nav statiski 254 00:10:57,670 --> 00:10:59,430 deklarēta vesela skaitļa. 255 00:10:59,430 --> 00:11:02,400 Vienīgais veids, kā es varu atsaukties uz šo zaļo lodziņu, ir atsaukt 256 00:11:02,400 --> 00:11:05,370 rādītāju uz b. 257 00:11:05,370 --> 00:11:07,940 Tātad b ir nosaukums, un tas ir statiski deklarēts. 258 00:11:07,940 --> 00:11:09,725 Bet es neizmantoju atsauci b, lai piekļūtu šai dinamiski piešķirtajai 259 00:11:09,725 --> 00:11:11,510 atmiņai. 260 00:11:11,510 --> 00:11:12,810 Un, protams, es to šeit nedarīšu. 261 00:11:12,810 --> 00:11:14,980 Bet pirmais, kas man jādara tūlīt pēc tam, ir pārbaudīt, vai b nav 262 00:11:14,980 --> 00:11:17,150 nulle. 263 00:11:17,150 --> 00:11:19,490 Ja b vērtība ir nulle, kaut kas ir nogājis greizi un man nekavējoties 264 00:11:19,490 --> 00:11:21,830 jāapturprogramma. 265 00:11:21,830 --> 00:11:25,020 Tālāk es varu teikt kaut ko līdzīgu: a ir vienāds ar & m. 266 00:11:25,020 --> 00:11:27,290 Ja atceraties no mūsu video par norādēm, būtībā tas nozīmē tikai 267 00:11:27,290 --> 00:11:29,560 punktus uz m. 268 00:11:29,560 --> 00:11:33,080 Tātad šeit tiek izveidota šī bultiņa. 269 00:11:33,080 --> 00:11:35,594 Tālāk pieņemsim, ka a ir vienāds ar b. 270 00:11:35,594 --> 00:11:37,682 Pirms es jums parādīšu, kas šeit notiks, vai varat mēģināt nedaudz 271 00:11:37,682 --> 00:11:39,770 uzminēt, kas tas būs? 272 00:11:39,770 --> 00:11:40,895 Apskatiet diagrammu. 273 00:11:40,895 --> 00:11:43,160 Padomājiet par to, kā attiecības varētu mainīties. 274 00:11:43,160 --> 00:11:47,850 Ja es saku a ir vienāds ar b, ko es saku? 275 00:11:47,850 --> 00:11:51,475 Es saku, ka a un b tagad norāda uz vienu un to pašu vietu, jo īpaši, 276 00:11:51,475 --> 00:11:55,100 a virzīsies uz punktu, uz kuru pašlaik norāda b. 277 00:11:55,100 --> 00:11:58,091 Tā vietā, lai norādītu uz m, a tagad norādīs šeit uz šo dinamiski 278 00:11:58,091 --> 00:12:01,082 piešķirto bloku, uz kuru es šobrīd varu tikai atsaukties — tagad varu 279 00:12:01,082 --> 00:12:04,073 uz to atsaukties vairākos veidos. 280 00:12:04,073 --> 00:12:05,570 Tagad es varētu teikt zvaigznīte a vai zvaigznīte b. 281 00:12:05,570 --> 00:12:08,615 Es varu uz to atsaukties abos gadījumos, jo abi tie paši statiski 282 00:12:08,615 --> 00:12:11,660 deklarētie mainīgie norāda uz vienu un to pašu lokāciju. 283 00:12:11,660 --> 00:12:13,077 Tad es varu teikt, ka m ir 10. 284 00:12:13,077 --> 00:12:15,410 Tā nav problēma, jo 10 tika deklarēti statiski. 285 00:12:15,410 --> 00:12:16,951 Tas ir lodziņš, par kuru es jau zinu. 286 00:12:16,951 --> 00:12:17,790 Tam ir nosaukums. 287 00:12:17,790 --> 00:12:20,845 Tātad, kad es saku, ka m ir vienāds ar 10, es tikai saku, ka 288 00:12:20,845 --> 00:12:23,900 ievietojiet 10 šajā zaļajā lodziņā ar nosaukumu m. 289 00:12:23,900 --> 00:12:27,046 Zvaigznīte b ir vienāda ar m plus 2. 290 00:12:27,046 --> 00:12:28,170 Tas ir nedaudz dīvaini, vai ne? 291 00:12:28,170 --> 00:12:29,270 Bet kas ir m plus 2? 292 00:12:29,270 --> 00:12:31,910 Nu, m ir 10, tātad 10 plus 2 ir 12. 293 00:12:31,910 --> 00:12:34,040 Un zvaigznīte b ir vienāda ar 12. 294 00:12:34,040 --> 00:12:36,950 Kad es saku zvaigznīte b, es atceļu atsauci uz b. 295 00:12:36,950 --> 00:12:40,610 Tāpēc es dodos pa bultiņu uz vietu, uz kuru b norāda. 296 00:12:40,610 --> 00:12:44,570 Un es tajā vietā ievietošu 12. 297 00:12:44,570 --> 00:12:45,920 Labi? 298 00:12:45,920 --> 00:12:48,510 Tālāk es dodos uz brīvu b. 299 00:12:48,510 --> 00:12:50,980 Tāpēc atcerieties, kas notiek ar free, ka mēs sakām sistēmai, ka 300 00:12:50,980 --> 00:12:53,450 vairs nestrādājam ar šo. 301 00:12:53,450 --> 00:12:54,560 Esam pabeiguši. 302 00:12:54,560 --> 00:12:56,095 Varat ņemt šos četrus baitus atpakaļ, vai arī neatkarīgi, kāds ir tā 303 00:12:56,095 --> 00:12:57,630 lielums. 304 00:12:57,630 --> 00:12:59,047 Tas ir četri baiti. 305 00:12:59,047 --> 00:13:02,420 Varat to ņemt atpakaļ un izmantot jebkurā citā programmā. 306 00:13:02,420 --> 00:13:05,930 Tātad, kad es atbrīvoju b, šī atmiņa būtībā pazūd. 307 00:13:05,930 --> 00:13:08,487 a un b joprojām norāda uz vietu, kur tas bija agrāk, bet man tas 308 00:13:08,487 --> 00:13:11,044 vairs nav pieejams. 309 00:13:11,044 --> 00:13:13,460 Ja es mēģināšu tai pieskarties, sistēma var tikt apdraudēta 310 00:13:13,460 --> 00:13:16,610 Piemēram, ja es mēģinātu pateikt šo — zvaigznīte  a ir 11 — kas 311 00:13:16,610 --> 00:13:19,760 notiks? 312 00:13:19,760 --> 00:13:21,447 Neprognozējama uzvedība. 313 00:13:21,447 --> 00:13:22,030 Mēs nezinām. 314 00:13:22,030 --> 00:13:25,406 Mēs varam iegūt segmentācijas kļūdu, jo mēs pieskaramies atmiņai, 315 00:13:25,406 --> 00:13:28,782 kuras vairs nav — mums vairs nav rakstīšanas tiesību. 316 00:13:28,782 --> 00:13:30,841 Jūs, iespējams, varat izvairīties no šīs problēmas, atkarībā no tā, 317 00:13:30,841 --> 00:13:32,900 kur sistēmā šī atmiņa atradās. 318 00:13:32,900 --> 00:13:33,860 Bet tas ir neparedzami. 319 00:13:33,860 --> 00:13:35,905 Tātad, kad esat atbrīvojis atmiņu, atcerieties, ka jūs sakāt 320 00:13:35,905 --> 00:13:37,950 sistēmai, ka man tā vairs nav vajadzīga. 321 00:13:37,950 --> 00:13:42,246 Tātad, ja jūs mēģināt to izmantot, var notikt dažas dīvainas lietas. 322 00:13:42,246 --> 00:13:45,088 Pie dinamiskās atmiņas piešķiršanas ir nedaudz dīvaini pierast, jo 323 00:13:45,088 --> 00:13:47,931 mēs esam ļoti pieraduši pie idejas izveidot mainīgo un piešķirt tam 324 00:13:47,931 --> 00:13:50,774 vērtību, un vienkārši manipulēt ar to. Tāpēc izmantojot norādes, lai 325 00:13:50,774 --> 00:13:53,617 kontrolētu atmiņas atrašanās vietu un ar norādēm tās netieši mainītu, 326 00:13:53,617 --> 00:13:56,460 var būt nedaudz dīvaini. 327 00:13:56,460 --> 00:13:58,420 Bet tikai turpiniet vingrināties ar to. 328 00:13:58,420 --> 00:14:01,345 Iekļaujiet šos noteikumus par to, kā veiksmīgi veikt malloc un 329 00:14:01,345 --> 00:14:04,270 atbrīvot, lai neizraisītu atmiņas noplūdes vai kaut ko tamlīdzīgu. 330 00:14:04,270 --> 00:14:06,710 Un jums vajadzētu veiksmīgi uzsākt darbu. 331 00:14:06,710 --> 00:14:07,750 Es esmu Dags Loids. 332 00:14:07,750 --> 00:14:09,730 Šis ir CS50.