PDA

Tam Sürümünü Görmek İçin : vector


ortug
26/05/2005, 20:20
Foruma bu ilk mesajım, herkese merhaba
Ders slaytlarında vector elemanlarının arda gelen bellek gözlerine yerleşeceğini belirten bir ifadeye rastladım. Yalnız bu mantığıma ters düştü. Nasıl olacak da ard arda bellek gözlerine yerleşecekler; ya ardından gelen bellek gözleri doluysa...


sckz
26/05/2005, 21:28
bir vector tanımladığın zaman vector baştan bir miktar bellek ayırır.. ve o bellegi doldurduğun zaman bu sefer daha büyüğünü ayırır ve eski verileri oraya kopyalar... artık kullanmadığı belleği de geri verir... zaten vector ün en zevkli yanı da budur (bence) (diğer container larda da benzer durumlar zevkli)... yani zen belleği cok fazla dert etmezsin...

ornegin elimizde gonul diye tanımlanmış bir vector var ve bunun o anki kapasitesini öğrenmek istiyoruz : gonul.capacity() bizim işimizi görüyo...

hatta aşağıdaki örnek dediğim bütün olayı açıklar....

vector<int> gonul;
for (int f=0; f!=100; ++f)
{
gonul.push_back(f);
cout << f << ", Kapasite : " << gonul.capacity() << ", Adres : " << &gonul[0] << endl;
}


bu kod un ciktisina dikkatli bak.. kapasitenin artığı heryerde gonul[0] ın (yani vector ün) adresi değişmiş...

mr1yh1
26/05/2005, 21:35
benim bildiği kadarı ile..
vector bir kapasiteye sahip , bu daima eleman sayısının üzerinde olmalı ..
eğer kurulu iken sen değer belirtmemişsen, default bir kapasite ile kuruluyor..
eğer yeni eleman eklemeleri ile kapasite aşılırsa,
yeni bir bellek bölgesini otomatik olarak alıp eski veriler buraya kopyalıyor..

bu durumda ,başka adrese taşınması mümkün olmayan şeyleri vektöre yerleştiremeyiz...

sckz
26/05/2005, 21:37
ha ekleyeyim. bazen büyük verileri vector içinde saklayabilirsin.. ve bana diyebilirsin o zaman... bu verileri taşıma işlemi bana (sana) pahalıya patlamaz mı?

o zaman önceden ne kadar kullanacağını kafanda kestirebiliyosan (örneğin 29 tane nesne miz var) gonul.reserve(29) diyip önceden ne kadar belleği senin için ayırması gerektiğini vector e söyleyebilirsin.

diyelim ki onu da kestiremiyorsun. o zaman nesne nin kendisinin vector ünü tanımlamak yerine nesneye işaret eden işaretçilerin vector ünü tanımlaman daha mantıklı olabilir..

ama bu seferde nolur.. vector senin işaretçilerinin bellek sorunlarıyla ilgilenir ama gerçek nesnelerinle ilgilenmek zorunda kalacak yine sensin... merak etme bunun da bi çözümü var.. o da akıllı işaretçiler kullanmak.. burdan sonrasını boost kütüphanelerinde daha tecrübeli bir arkadaşın yanıtlaması daha iyi olur.

sckz
26/05/2005, 21:57
ha yine ekleyeyim .... Hoş Geldin :hey:

ceeyt
26/05/2005, 22:10
ya ardından gelen bellek gözleri doluysa...
C, C++ ta kullanicinin bellegi dinamik olarak yonetebiliyor olmasina karsin, bu kadar ayrintili bir islem bu siniri asiyor.C,C++ kullanirken bunu dusunmene gerek yok.
ha ekleyeyim. bazen büyük verileri vector içinde saklayabilirsin.. ve bana diyebilirsin o zaman... bu verileri taşıma işlemi bana (sana) pahalıya patlamaz mı?

o zaman önceden ne kadar kullanacağını kafanda kestirebiliyosan (örneğin 29 tane nesne miz var) gonul.reserve(29) diyip önceden ne kadar belleği senin için ayırması gerektiğini vector e söyleyebilirsin.


Bir ara Ali Cehreli bir sorumu yanitlarken - Bejarne Stroustrup'un ( dogru mu yazdim :) ) bir yazisini da referans gostererek - 'reserve' islecinin kullanimindan buyuk olcude vazgecildigini de soylemisti.

Ozellikle 20-30 nesnelik bir reserve islevi astarin yuzunden pahaliya gelmesine bile sebep olabilir( emin degilim )

sckz
26/05/2005, 22:54
şimdi reserve diye arattırdığımda (forumda) gecen muhabbeti buldum.. ortug kardeşim o sohbete de bi bak derim : http://forum.ceviz.net/showthread.php?t=14998

sckz
26/05/2005, 23:09
ben yokken bu forumda kaçırdığım çok güzel satırları şimdi görüyorum.. şunu da bir okuyun derim : http://forum.ceviz.net/showthread.php?t=16605

Euclides
27/05/2005, 12:00
bir vector tanımladığın zaman vector baştan bir miktar bellek ayırır.. ve o bellegi doldurduğun zaman bu sefer daha büyüğünü ayırır ve eski verileri oraya kopyalar... artık kullanmadığı belleği de geri verir... zaten vector ün en zevkli yanı da budur (bence) (diğer container larda da benzer durumlar zevkli)... yani zen belleği cok fazla dert etmezsin...

Bence son derece dert edilecek bir şey..

http://forum.ceviz.net/showthread.php?t=17549
acehreli çok güzel bir mesajı var
http://forum.ceviz.net/showpost.php?p=136613&postcount=2
http://forum.ceviz.net/showpost.php?p=139624&postcount=6

sckz
27/05/2005, 16:33
evet.. okudum şimdi.. gerçekten hoş olmuş... dert etmezsin yerine uğraşmaszın deseydim daha doğru olurdu herhalde .. ama bu bellek işini biz yapsaydık farklı bişi mi yapçaptık..

senin bu konudaki çözüm önerilerini de okumak isterim... vector yerine başka bişi kullanın gibi cümlelerin istemediğimi belirtmek isterim... ve tepede arkadaşımın sorusunun vektörlerle ilgili olduğunu hatırlatırım...

ek olarak orada okudum sorunun daha çok realloc() kullanımıyla ilgili olduğunu hatırlatırım.. ve yine http://www.research.att.com/~bs/new_learning.pdf adresine bi kliklersen.. bjarne stroustrup un malloc(), realloc() gibi hafızayla direk uğraşmak yerine vector ü tercih ettiğini görebilirsin (belki de bunu geyik olsun diye ya da daha anlaşılır olsun diye kullanmıştır.. onu bilemeyiz)... ve yine yannış hatırlamıosam (yannış hatırlamıosam) bjarne stroustrup bu camia da önemli kişilerden biri...

ve yine eklersem, kayıt defteri gibi bir uygulamada bu pekte sorun olmaz öğle değil mi ;) :p

Euclides
27/05/2005, 18:37
1...
oradaki problem realloc'dan değil
lütfen 2. link'i terar oku

"Ileriyi gormeden yapilmis kotu bir tasarim olarak kabul edilir."(Arc...)

2..
ben mi yanlış okudum yoksa sadece kısa olduğu içi mi yazıyor ??

3...
Önce şunu soralım o zaman "kayıt defteri"'inde limitleri bilinmeyen neden vector kullanalım ?
(tabii ki bu değerlendirmeyi yaparken tüm zor işi 3. parti bir veri tabanı server'ına yaptırdığımızı düşünüyorum. yoksa zaten STL bizi çok pis öper... :) )

Zor işleri her ne kadar başkaları yapsana bizde bir câhillik edelim.
10000 adet müşterimiz olsun
programımız bankamızla son 1 ay içinde işlem başına ortala X YTL'den fazla olan müşterileri bulacak.
Program 10000 kişiyi bilmiyormuş gibi DB'den teker teker her müşteri alsın ve vector<adam> şeklinde bir vector'e eklesin...

bakalım ne kadar etkiliyor ?
(sen birde bunu distributed bir app gör :) :) )

mr1yh1
27/05/2005, 19:19
spool memory diye birşey var, ( STL de değil )
bunun bağlı liste ile kullanımı nasıl olur peki ?
bağlı listenin
bellek ayırma/bırakma işlemlerindeki hız kaybını azaltabilir
ve vectordeki gibi elemanların taşınması gerekmez..
ben bunu daha önce kullanmadım ,
zaten bende bu imkanı sağlayacak bir kütüphane de yok ( bildiğim kadarı ile :) ) yani sonucu merak ediyorum..

sckz
27/05/2005, 19:53
realloc, Herb Sutter ve Andrei Alexandrescu'nun C++ Coding Standards kitaplarinin besinci maddesinde kotu tasarim ornegi olarak gecer:

<ceviri>
realloc standart C'de UnlU bir kotu tasarim ornegidir. Cok fazla sey yapmak zorundadir: NULL gonderilirse bellek ayir, buyukluk olarak 0 gonderildiginde bellegi geri ver, eger olabiliyorsa nesnelerin yerini degistirmeden tekrar ayir, eger olamiyorsa nesneleri baska bir yere tasi. Kolayca genisletilemez. Ileriyi gormeden yapilmis kotu bir tasarim olarak kabul edilir.
</ceviri>

Ali
<->
oradaki problem realloc'dan değil
lütfen 2. link'i terar oku
"Ileriyi gormeden yapilmis kotu bir tasarim olarak kabul edilir."(Arc...)

ve verdiğim linkle alakalı : sadece kısa olduğu için değil aşağı inersen hızın da önemli olduğunu görebilirsin...

ve neden kayıt defteri diye bişi kullandım.. çünkü daha önceki yazılarından birinde böyle bişi geçtiğini hatırlıyorum... bende geyik olsun diye onu yazmıştım...

ayrıca sende yazmışsın zaten neden ben 10000 kullanıcının verisini programım içine çekip arattırayım ki... sql diye bişi var... peki aslında mysql gibi bir veritabanı sunucusu da c++ ya da başka bir dille yazılan bir program değilmi... sonucta biz ona sql kodunu veriyoruz... o ilgili olanları bulup bize veriyo.. bizim programımız yavaş ta.. mysql neden hızlı sonucları buluyo.. eğer mysql de verilerin hepsini tablolardan çekip aramayı yapıp bize sonucu ulaştırsaydı, bizim programımızdan pek bir farkı kalmayacaktı... o zaman burdan şu sonuç çıkıyo... veri tabanında tutulan bilgiler öyle her gelen sona gibi bir yapısı yoktur (tabi isterseniz böyle de yaparsınız).. eğer öyle olsaydı yahoo da mail okumak için login işleminin ne kadar süreceğini varın siz hesap edin...

sckz
27/05/2005, 20:22
ve biras sapacak olursak : sql sadece SELECT * FROM gonulTablosu gibi cümlelerden oluşmaz (yani sadece veritabanına bilgi gir, sil vs vs değildir)... ve sql sadece structured query language da değildir.. bu eski bir isimdir ve sql in şimdiki yeteneklerini karşılayacak bir isim değildir ... (aynı php de olduğu gibi...)

Sabahi
28/05/2005, 07:34
<->

eğer mysql de verilerin hepsini tablolardan çekip aramayı yapıp bize sonucu ulaştırsaydı, bizim programımızdan pek bir farkı kalmayacaktı...


Aslina bakarsan gerek mysql gerek diger veritabanlari olsun tam olarak yukarida yazdiginizi yapiyor yani tablolardan cekip cikariyor. Bir database in hizini belirleyen tasariminda kullanilan algoritma tamamen. Tabi calistigi bilgisayarin hizi, OS v.s. gibi faktorleri goz ardi edersek yada esit tutarsak.

SQL e gelince o da basitce bes kisima ayrilabilir
1) Data Retrieval (select statements)
2) DML (Data Manipulation Language) (Insert, update, delete)
3) DDL (Data definition Language) (Create, alter, truncate, rename, drop)
4) Transaction Control(Commit, rollback, savepoint)
5) DCL (Data Control Language) (Grant, Revoke)

Bunlarin otesindekiler sql sayilmamali. Mesela Oracle sql e ek PL/Sql denilen Pascal turevi bir dil eklemis ve bu sayede yalin sql kullanarak yapilamayacak islemlerin yapilabilmesini saglamistir ama bu tur uygulamalari SQL ile karistirmamak lazim. Tabi bu konuda bir uzman olmadigin icin yanlis dusunuyor olabilirim. Hatam varsa affola.

Euclides
28/05/2005, 11:13
ayrıca sende yazmışsın zaten neden ben 10000 kullanıcının verisini programım içine çekip arattırayım ki... sql diye bişi var... peki aslında mysql gibi bir veritabanı sunucusu da c++ ya da başka bir dille yazılan bir program değilmi... sonucta biz ona sql kodunu veriyoruz... o ilgili olanları bulup bize veriyo.. bizim programımız yavaş ta.. mysql neden hızlı sonucları buluyo.. eğer mysql de verilerin hepsini tablolardan çekip aramayı yapıp bize sonucu ulaştırsaydı, bizim programımızdan pek bir farkı kalmayacaktı... o zaman burdan şu sonuç çıkıyo... veri tabanında tutulan bilgiler öyle her gelen sona gibi bir yapısı yoktur (tabi isterseniz böyle de yaparsınız).. eğer öyle olsaydı yahoo da mail okumak için login işleminin ne kadar süreceğini varın siz hesap edin...

Zor işleri her ne kadar başkaları yapsana bizde bir câhillik edelim.

Daha söylecek bir laf var mı ?
allah islah etsin...

sckz
28/05/2005, 12:40
@Sabahi +1
@Euclides
bende aksi bişi söylemedim zati... Söylediklerim seninkisine ek olarak gözükebilir..

geri kalan kısmı sana özel mesaj olarak attım... bu konunun sapmasını istemiyorum...

gsocnkuzl
10/06/2005, 12:15
kapasitenin artığı heryerde gonul[0] ın (yani vector ün) adresi değişmiş...

evet haklısın kapasitenin arttığı heryerde gonul[0] ın adresi değişmiş. ama bu vector un adresi değişmiş demek değildir. vector<int> gonul; static bi veri dir.. ve bellek adresini değiştiremezsin. belleği değişen vector un kendisi değil, vector ün içinde barındırdığı veriler.

bir vector içinde _Myfirst, _Mylast, _Myend diye üç tane işaretçi bulundurur. bunlardan _Myfirst dizinin ilk elemanını bize verir. aşırı yüklenmiş [] operatorune vereceğimiz argüman bu _Myfirst degeri ile toplanıp dereferans edilir. _Mylast ise dizinin son + 1 elemanının adresini gosterir. _Myend ise ayırdığımız kısma yerleştirebileceğimiz son elemandan bir sonraki elemanın adresini gosterir 8). verilen ornekte _Myend in tipi int*.. Bu yüzden kapasite herzaman eleman sayısından büyük olmalı (eşit olmamalı).. eğer eşit olursa _Myend bir int* e işaret etmeyebilir..

acehreli
10/06/2005, 22:39
gsocnkuzl, hosgeldin ;)

vector'un icinde ne bulundurdugunu standart soylemez. _Myfirst gibi nesneler, senin ortamindaki vector gerceklemesinde kullaniliyorlar ama baskalarinda bulunmayabilir.

Standart yalnizca vector'un arayuzunu, performansini (algoritma karmasikligini), ve hangi islem sonucunda hangi vector erisicilerinin (iterator) gecersiz hale gelecegini belirler. (Eminim baska seyler de belirliyordur. :) )

Kapasite'nin eleman sayisindan buyuk olmasi geregi de senin ortaminin getirdigi bir sonuc olmali. Cunku ben g++ 2.95 ile soyle bir sonuc aldim:


$ tail -15 deneme.cpp; ./deneme
#include <iostream>
#include <vector>

int main()
{
std::vector<int> sayilar;

for (int i = 0; i != 10; ++i)
{
std::cout << "kapasite: " << sayilar.capacity()
<< " nesne sayisi: " << sayilar.size()
<< '\n';
sayilar.push_back(i);
}
}
kapasite: 0 nesne sayisi: 0
kapasite: 1 nesne sayisi: 1
kapasite: 2 nesne sayisi: 2
kapasite: 4 nesne sayisi: 3
kapasite: 4 nesne sayisi: 4
kapasite: 8 nesne sayisi: 5
kapasite: 8 nesne sayisi: 6
kapasite: 8 nesne sayisi: 7
kapasite: 8 nesne sayisi: 8
kapasite: 16 nesne sayisi: 9


Ali