C ++ qanday qilib to'g'ri xotirani bo'shatadi?

int main(){
    int *a = new int[5];
    int *b = new int[10];
    int *c;
    for (int i = 0; i < 5; ++i){
        a[i] = i * i;
    }
    for (int i = 0; i < 10; ++i){
        b[i] = 50;
    }
    c = a;
    a = b;
    delete[]b;
    delete[]c;
    return 0;
}

Yuqoridagi kodni bajarganingizdan so'ng, a xotirasi dastlab ozod qilinganligiga ishora?

Agar yo'q bo'lsa, qanday qilib to'g'ri tarzda ozod qilish kerak?

~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

a ko'rsatgichidan foydalaning, shuning uchun uni to'g'ridan-to'g'ri o'chirish taqiqlanadi.

ushbu kodning maqsadi b ga tegishli xotiraga dastlab a orqali kirish va ulardan to'g'ri foydalanilgan xotirani bo'shatishdir.

4
Hatto bunday noan'anaviy misolni bir qarashda 100% tekshirish qiyin. Bosh maslahat, albatta, xom belgilaridan qochish va aqlli ko'rsatgichlardan foydalanish; va agar bu mumkin emas yoki xohlamasa, asl nusxada saqlanadigan manzili saqlanadigan joyga joylashtiraman. Erkinlik faqat bu o'zgaruvchilar orqali sodir bo'ladi. Buning uchun vector s foydalanish mumkin. Natijada, amalga oshirilgan bo'lsa, u aqlli ko'rsatgichlarga o'xshab juda ko'p narsalarni ko'rib chiqa boshlaydi (masalan, siz misollarni hisoblashni xohlashingiz mumkin).
qo'shib qo'ydi muallif Peter A. Schneider, manba
Ha, siz a xotirasini c orqali o'chirib tashlaysiz.
qo'shib qo'ydi muallif Sombrero Chicken, manba
Nima uchun to'g'ridan-to'g'ri a va b yo'q qilmaysiz? Bu sizga bosh og'rig'ini tejashga yordam beradi.
qo'shib qo'ydi muallif byxor, manba

6 javoblar

Ha, xotira ozod. Shunga qaramasdan, ko'rsatgich ko'rsatadigan narsani o'zgartirganda juda ehtiyot bo'lish kerak, chunki u xotiraning sızmasına olib kelishi mumkin.

2
qo'shib qo'ydi

Ha, u bor. Pointer manzillarni o'z ichiga olgan oddiy o'zgaruvchilar. Chunki, a. Sizning birinchi ajratishingiz ozod.

1
qo'shib qo'ydi

ozod.

Chunki c = a; dan so'ng, c dastlab ko'rsatilgan a xotira manzilini saqlaydi. Siz delete [] c; tomonidan c ni ozod qildingiz.

// Assume originally a -> 1, b -> 2

c = a; //Now a -> 1, b -> 2, c -> 1
a = b; //Now a -> 2, b -> 2, c -> 1

a yoki b ni ozod qila olasiz, ulardan kamida bittasi, bir xil xotira bloklarini ko'rsatadi. c kodini ozod qilishingiz kerak.

1
qo'shib qo'ydi

Yuqoridagi kodni bajarganingizdan so'ng, xotirada "a" xotirasi bor   ozod qilinganligiga ishora bormi?

Ha, xotira ozod. c = a sifatida delete [] c; a xotirasini o'chiradi.

However, you don't need *c to clear memory, just directly delete a and b

delete[]a;
delete[]b;

UPDATE

Javobingizni tahrir qilganingiz va endi nimaga erishmoqchi ekanligingiz yanada aniqroq, ya'ni. a orqali ko'rsatiladigan kirish xotirasi a orqali, lekin undan oldin a belgisi bilan xotirani bo'shatishni xohlaysiz. Shunday qilib, nima qilish kerak:

1- First free the memory pointed to by a

delete []a;

2- Now point a to the memory location pointed to by b

a=b;

Endi a tomonidan ko'rsatiladigan xotira holati o'chirildi va a hozirda b ishora qilayotgan joyga ishora qiladi.

Note: Keep in mind that now when you have both a and b pointing to the same memory location, if you use either delete []a or delete []b, memory location pointed to by both a and b will be cleared.

1
qo'shib qo'ydi
@byxor nuqtasi qayd etildi. OS tizimini olib tashlandi
qo'shib qo'ydi muallif Yousaf, manba
@RubySapphire kodi b ba'zi bir xotira joyiga ishora qilgan ekan. b tomonidan ko'rsatilgan xotirani o'chirib tashlaganingizdan so'ng, b belgisi bilan ko'rsatilgan xotiraga markerni a
qo'shib qo'ydi muallif Yousaf, manba
@RubySapphire yangilangan javobni ko'ring.
qo'shib qo'ydi muallif Yousaf, manba
marker a orqali ishora qilish uchun foydalaniladigan b xotirasiga kirish uchun to'g'ri bo'ladimi?
qo'shib qo'ydi muallif Ruby Sapphire, manba
u ishlaydi, juda ko'p rahmat.
qo'shib qo'ydi muallif Ruby Sapphire, manba

delete ni emas, balki belgisi ustida ishlaydigan, lekin ko'rsatadigan ob'ektda o'ylashingizdan oldin, imho juda ko'p tartibsizliklardan qochish mumkin. Yo'qotilgan ko'rsatgich emas, balki qator. O'zingiznikiga o'xshash bo'lgan ushbu misolni oling:

struct Foo { 
     int id; 
     Foo(int i) : id(i) {} 
}; 
Foo* a = new Foo(1);
Foo* b = new Foo(2);
Foo* c;
c = a;
delete c;
c = b;
delete c;

c ustida faqatgina o'chirish c; ta'siri shundan iboratki, uni keyinchalik o'chirishga ruxsat etilmaydi, lekin o'chiriladi, avval Foo ob'ekti id 1 va keyin id 2 bilan birga.

0
qo'shib qo'ydi

Yana bir usul - optimallashtirish haqida o'ylashingiz mumkin. Ehtimol, bu erda xotirani ajratishning hojati yo'q. Bu ishni ko'rib chiqing

int a[5];
int b[10];

int func(int param) {
    for (int i = 0; i < 5; ++i){
        a[i] = i * i;
    }
    for (int i = 0; i < 10; ++i){
        b[i] = 50;
    }
}

int main(){
    for (int i = 0; i < 10000; ++i){
        func(i);
    }
    return 0;
}

Iteratsiya uchun/bo'sh xotira ajratishning hojati yo'q. Ammo agar siz juda ko'p ishlamoqchi bo'lsangiz, u biroz murakkabroq bo'ladi.

Shu kabi usul yordamida men fan uchun loyihada hisob-kitoblarning tezligini sezilarli darajada yaxshilab qo'ydim.

Sizning kodingiz hamma uchun ochiq bo'lishi kerak. Sizdan keyin kim bo'lishini o'ylab ko'ring. Agar o'qish imkoniyati va tezlikni tanlash - okunabilirliği seçmelidir.

0
qo'shib qo'ydi