From: Nilgün Belma Bugüner (nilgun@superonline.com)
Date: Mon 15 Sep 2003 - 13:59:14 EDT
Selam,
Tam da libc kılavuzunun yeni çevirdiğim bir konusuna rastgeldiniz.
malloc kullanmayın, çok tehlikeli.
Çeviriden bazı bölümler:
Büyüyen Nesneler
Yığınak tomarları içindeki bellek sıralı erişimle kullanıldığından,
bir nesneyi, nesne için ayrılan alanın sonuna bayt ya da baytlar ekleyerek
adım adım oluşturmak mümkündür. Bu teknikle, bir nesneye veri aktarırken acaba
yer kaldı mı diye düşünmeniz gerekmez. Bu tekniğe Nesnelerin Büyütülmesi diyoruz.
Bu bölümde nesneleri sonuna veri ekleyerek büyütmek için kullanılan özel
işlevlere yer verilmiştir.
Bu işlevlerden birini kullanarak nesneye veri eklemek istediğinizde nesnenin
büyütülmesi özdevinimli olarak gerçekleştiğinden, bir nesneyi büyütmeye başladığınızda
özel olarak hiçbir şey yapmanız gerekmez. Ancak büyütme işlemi bittiğinde, bittiğinin
belirtilmesi gerekir. Bunun için obstack_finish işlevi kullanılır.
Büyütme işleminin bittiği belirtilene kadar her veri eklemesinde nesne yeni bir tomara
kopyalandığı için nesnenin büyütülmesi bitene kadar nesnenin gerçek adresi bilinmez.
Bir yığınak bir nesneyi büyütmek için kullanıldığında, bir başka nesneyi o yığına
yerleştiremezsiniz. Bunu yapmayı denerseniz, eklediğiniz nesneye ayrı bir nesne olarak
erişilemez; büyütülen nesneye bir alan eklenmiş olur ve eklediğiniz nesne büyütülen
nesnenin bir parçası haline gelir.
....
.....
Demekki, obstack_room ile yeterli yer kalmadığını her anladığınızda
normal büyütme işlevlerini kullanabilecek ve nesneniz yeni bir tomara
kopyalandığında tekrar hızlı büyütme işlevlerini kullanabileceğiniz
güvenilir bir alana sahip olabileceksiniz.
Burada bir örnek var:
void dizge_ekle (struct obstack *yiginak, const char *dizge, int uzunluk)
{
while (uzunluk > 0)
{
int bosyer = obstack_room (yiginak);
if (bosyer == 0)
{
/* Yeterli boş yer yok. Bir karakter eklersek nesnemiz
yeni bir tomara kopyalacak ve boş yer olacak. */
obstack_1grow (yiginak, *dizge++);
uzunluk--;
}
else
{
if (bosyer > uzunluk)
bosyer = uzunluk;
/* Boş yer olduğuna göre hızlı olarak ekleme yapabiliriz. */
uzunluk -= bosyer;
while (bosyer-- > 0)
obstack_1grow_fast (yiginak, *dizge++);
}
}
}
Çeviri örnek kodları da kapsıyor mecburen :-)
obstack.h dosyasını unutmayın.
Normal büyütme işlevleri yer kalıp kalmadığını sürekli denetler, bu nedenle yavaş,
hızlı işlevler bu denetimi yapmaz. Bu örnekte yer kalmadığında normal işlev kullanılarak
tomar büyütülmüş (daha büyük bir tomar ayırarak), sonra hızlı işlevle devam edilmiş.
akım: stream
yığınak: obstack
tomar: chunk
Bu bellek ayırma konusu derin bir mevzu. Şu patent yasası olayı bitsin, belgeler.org'da
libc çevirisini kısmen de olsa yayınlayacağım (kısmet olursa... ).
AB Patent yasası ile ilgili mevzu dernek listesinde tartışmaya açıldı.
Esen kalın,
Nilgün
Pazartesi 15 Eylül 2003 18:02 sularında, Murat ALKAN şunları yazmıştı:
> Merhaba,
>
> Programimda kullanmak icin seek2line( adli bir fonksiyon yazdim..
> Fonksiyonun amaci \n karakterlerini sayarak herhangi bir satiri TEK basina
> gostermek.
> Fonksiyon soyle:
> char * seek2line(char *where,int line){
> int s;
> char *seek2;
> seek2=malloc(500);
> // Tahminen burada segmentation fault.
> sprintf(seek2,where);
> for(s=1;s!=line;s++){
> sprintf(seek2,(strchr(seek2,'\n'))+1);
> }
> return strtok(seek2,"\n");
> }
>
> Yukarida yazdigim gibi sprintf fonksiyonunu kullanirken segfault aliyorum..
> Bir de fonkisyonu su sekilde kullandigimda hata almiyorum:
> buffer=seek2line("Deneme\nSegfault\n3.satir\n",2);
> Ama su sekilde kullandigimda hata...:
> for(count=1;sprintf(parser,seek2line(conf,count));count++){
>
> Nedir problem.. yardimlariniz icin simdiden tesekkurler..
>
> Murat ALKAN