[c] Hoe weet free hoe groot de malloc was?

Pagina: 1
Acties:

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Ik probeer in m'n AI het volgende te bouwen; een malloc van pagesize, waardoor de eerste op null komt en ik gewoon met pointers (in de malloc) ed kan werken en 'imagen' naar de hd zonder alles om te hoeven zetten. So far, so good. Dat heb ik nog niet werkend, maar daar ben ik dan ook nog niet aan begonnen.
Ik wil namelijk ook dat als m'n page vol zit ik er een tweede page achter kan plakken. Hier ben ik al wel de hele dag mee in de weer. Om dit te laten werken doe ik wat vuile pointer -> int en int -> pointer casts, maar het werkt prachtig. Denk ik iig, want mem leaks zijn lastig te zien (als iemand het hier niet mee eens is, 1) bekijk m'n code en geef commentaar of 2) vertel me hoe ik kan checken op mem leaks in freeBSD, dank dank, maar niet m'n eigenlijk vraag :) ) en ik heb tot nu toe geen system crashes gehad, wat ik eigenlijk zo wil houden.
De vraag rees alleen, hoe weet free aan het einde nog hoe groot de malloc was als ik de pointer in de tussentijd naar een tiental andere mallocs heb laten wijzen? Hoe gaat dit zowiezo? In mijn geval zijn alle mallocs even groot, maar wat als dat niet zo is?
M'n idee was dat de kernel aan gemallocceerde geheugenadressen knoopt wat de grootte was en dit ergens bij houd. Ik kan dit alleen nergens bevestigd vinden (en heb verder geen diepe kennis van kernels) en wil toch er zeker van zijn dat ik niet met een hele lading memory leaks zit aan het einde van het verhaal.

Voor de B), m'n test code staat hier. En voor degene die denkt dat de casts niet nodig zijn als ik een struct aan maak, vertel mij maar hoe ik een class zo bouw dat er eerst een pointer komt, dan alle beschikbare ruimte in m'n page (getpagesize - 2 pointers) en tot slot weer een pointer. Leek mij onmogelijk, en dit werkt goed. Okeej... het werkt niet op 64 bit systemen (of iig systemen met pointers anders dan 4 bytes groot) maar daar kan ik (voorlopig) nog mee leven.

Spolap: Interactive webcomic


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat heeft ie ergens geregistreerd natuurlijk, wat denk je anders :)

En een pointer is niets meer dan een verwijzing naar een stukje geheugen. Je kunt een pointer dus best ergens anders naartoe laten wijzen, casten naar int, etc. Het gaat om het uiteindelijke geheugen dat je free'd, niet de pointer zelf.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Voor het opvragen van het formaat van een malloc is geen StdC-lib oplossing, maar zijn vaak wel platform-specific oplossingen, zoals op Windows _msize. Wat ook kan is natuurlijk iets simpels als dit (wel platformindependent):
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void* mymalloc(size_t p_Size)
{
void* l_Block = malloc(p_Size + sizeof(int));
*((int*)l_Block) = p_Size;
return l_Block + sizeof(int);
}

void myfree(void* p_Block)
{
free(p_Block - sizeof(int);
}

int mygetsize(void* p_Block)
{
return *((int*)(p_Block - sizeof(int));
}

Sim-pel :+

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Weet je zeker dat je niet gewoon je eigen memory manager wilt schrijven? Dan kun je de pages direct bij het besturingssysteem opvragen in plaats van van de grillen van je C-library implementatie afhankelijk te zijn. OS-specifieke code is natuurlijk niet portable, maar ik heb zo'n vermoeden dat je huidige code dat ook niet is; wie garandeert je dat je pointers op page boundaries krijgt? Je kan sowieso niet op een portable manier bij de geheugenstructuren komen die malloc/free gebruiken.

edit:
In de praktijk doet malloc trouwens ook zoiets als wat curry voordoet.

[ Voor 9% gewijzigd door Soultaker op 21-09-2003 23:55 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Curry: Overigens wil je je gealloceerde data meestal op 16 bytes (oid) aligned ;)

[ Voor 9% gewijzigd door .oisyn op 21-09-2003 23:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Ik meen me te herinneren dat er een byte of 4 voor je allocated mem wat data staat over de hoeveelheid. Pin me hier niet op vast ;)

lees anders even de replies boven je :z :+

anders reply je ipv een edit :P
en mijn edit was dat ik net wilde toevogen dat .oisyn dat eigenlijk ook deed :+

Een reply kickt de topic onnodig :Y) Bovendien was het curry's code, niet die van mij. En het was ook curry die de vorige edit deed ;)

Oops :+ Dat het zijn edit was wist ik wel, code had ik even fout gekeken ;)

dommie ;)

zodra je een weekje mod bent vergis je je niet meer zo snel in die knoppies hoor :+ oh ja oisyn's replies zijn nu blauw en die van curry684 donkerrood :D

Nu niet meer >:) :D

[ Voor 113% gewijzigd door .oisyn op 22-09-2003 12:51 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Soultaker schreef op 21 September 2003 @ 23:53:
Weet je zeker dat je niet gewoon je eigen memory manager wilt schrijven?
Ja :+
Ik wilde een simpel AItje schrijven om m'n theorie te testen. Daarvoor had ik asynchrone input nodig, dus kwam pthread al om de hoek kijken. Het moest er ook nog een *beetje* uitzien (en werken met die threads zonder een complete bende van m'n terminal te maken) dus kwam curses om de hoek kijken. En om nu genoeg ruimte te krijgen zit ik met pointers in mallocs die naar andere mallocs wijzen te klooien. Ik vind het wel diep genoeg voor een check op een theorie.
Besides, en misschien wel het beste argument voor het niet maken van een eigen memory manager; ik heb er de ballen verstand van :) Tis m'n eerste flinke progsel onder unix.
...wie garandeert je dat je pointers op page boundaries krijgt?
#man malloc ;) (als je dus pagesize of groter doet)

Maar ik loop verder dus geen risico op memleaks op deze manier? Dan kan ik met een gerust hart gaan slapen :z

Spolap: Interactive webcomic


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
wacco schreef op 22 September 2003 @ 00:04:
#man malloc ;) (als je dus pagesize of groter doet)
Krijg nou de...! Dat was me nog niet eerder opgevallen. Weer wat geleerd. :)
Maar ik loop verder dus geen risico op memleaks op deze manier? Dan kan ik met een gerust hart gaan slapen :z
Nou, ik heb maar vluchtig gekeken, maar volgens mij schrijf je op allerlei plekken waar je niet bij mag. Verwijst 'pin' op regel 26 bijvoorbeeld niet naar een gebied van 10 bytes? Dan kun je daar geen 10 ints in kwijt!

Verder vind je for-lus nogal ingewikkeld; ik kan me voorstellen dat het werkt, maar ik denk dat een while-lus met duidelijk onderscheid tussen eindconditie (zonder assignment dan hopelijk!) en welk werk er daadwerkelijk in de lus verricht wordt, overzichtelijker zou zijn geweest.

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Hmm over die 10 ints / 10 bytes heb je volgens mij gelijk. Was me nog niet opgevallen na het eruit slopen van alle andere code (het was eerst een bende). Is erin geslopen waarschijnlijk.
Nog een malloc hierachteraan (het idee was om dat stukje steeds te herhalen) zou waarschijnlijk idd problemen geven bij de free. En die for lus is idd een beetje cryptisch... misschien dat ik daar nog wat simplistischer uit de hoek kan komen. Ik heb hem even als do - while geupload, maar nog niet getest. Ben namelijk meteen verder gaan knutselen aan dat int probleempje.
Een int is 4 bytes dus heb ik maar de even malloc aangepast. Ga er naast deze pointers toch alleen maar ints in wegschrijven. malloc(10) is malloc(3 * 4) geworden en pin[2] schrijven we naar weg. Later, met pagesize (die bij mij 4096 is, 1024 ints :) ), deel ik het door vier (ipv 4 keer de pagesize).

Ging eigenlijk slapen maar jullie reageerden zo fanatiek dat ik na een half uurtje het niet kon laten om er toch weer achter te kruipen :P Maar ja, morgen weer een dag (en die begint om half zeven...)

Spolap: Interactive webcomic


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

malloc(3 * 4)
als je netjes wilt coden schrijf je: malloc (3 * sizeof (int)) :)
Is het nog portable ook :) (hoewel ik me nog steeds afvraag in hoeverre je wilt porten naar systemen met een ander native int formaat)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

.oisyn schreef op 22 September 2003 @ 01:18:
[...]


als je netjes wilt coden schrijf je: malloc (3 * sizeof (int)) :)
Is het nog portable ook :) (hoewel ik me nog steeds afvraag in hoeverre je wilt porten naar systemen met een ander native int formaat)
Ik heb ook subtiel het gevoel dat ie mijn post niet gelezen heeft :/ :+

Professionele website nodig?


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Mja maar mja maar mja maar... curry schrijft enge code! :+
De sizeof(int) is idd netter, ik weet het, maar ik zei toch dat het een tijdelijk iets is. In het uiteindelijke proggie komt er malloc(getpagesize()) te staan... Dan kan ik daarna wel gaan delen met aantal_ints_in_page = getpagesize() / sizeof(int); máár niemand heeft schijnbaar nagedacht over de effecten als sizeof(int) geen 4 returned en ik wel m'n hele 'image' (met ints van 4) van de hd weer lekker radicaal in het geheugen mik. Krijg je toch plots een hoop onzin.
Wil je dit progje later porten (in z'n volledigheid) dan zal je toch ook de hele database moeten gaan omrekenen naar andere sizeofs. Kan-ik-wel-weer de database portable gaan maken nú maar dan heb ik weer geen ruk aan m'n pagesize alligning dinges :)

...en ik wilde het juist nog een 'beetje' simpel houden :D

[ Voor 6% gewijzigd door wacco op 22-09-2003 01:36 ]

Spolap: Interactive webcomic


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Curry: overigens werkt jouw code niet, want een void * heeft geen size, dus pointer arithmetic werkt niet :P

(als je nou cast naar int * dan kun je gewoon + 1 en - 1 doen ;))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

overigens werkt jouw code niet, want een void * heeft geen size, dus pointer arithmetic werkt niet
Mjah was in de bonen, dacht even dat dat bij C weer wel kon... maar u heeft gelijk het was laat :D

Professionele website nodig?


Verwijderd

curry684 schreef op 21 September 2003 @ 23:49:
Voor het opvragen van het formaat van een malloc is geen StdC-lib oplossing, maar zijn vaak wel platform-specific oplossingen, zoals op Windows _msize. Wat ook kan is natuurlijk iets simpels als dit (wel platformindependent):
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void* mymalloc(size_t p_Size)
{
void* l_Block = malloc(p_Size + sizeof(int));
*((int*)l_Block) = p_Size;
return l_Block + sizeof(int);
}

void myfree(void* p_Block)
{
free(p_Block - sizeof(int);
}

int mygetsize(void* p_Block)
{
return *((int*)(p_Block - sizeof(int));
}

Sim-pel :+
Deze oplossing heb ik ook meerdere malen gebruik om te controleren op memory leaks. Bij myalloc tel je de size van het gealloceerde geheugen op bij een globale variabele en bij de myfree lees je de size weer uit en trek je dat weer af van die globale teller. Werkte perfect en zoals je zei, het is portable.

Laats heb ik echter een simpel shared libje geschreven die echt als wrapper dient en dus de echt libc malloc/free override door te preloaden. Dit gaf echter heel veel problemen, al mijn eigen functie aanroepen gingen zonder problemen. Maar aanroepen van standaard functies liepen vaak uit op segfault op het moment van free'en. Een van die aanroepen was 'dlclose' voor het unloaden van een dynamische geladen library.

Zou dit te maken kunnen hebben met eventuele aanroepen van realloc, die dan niet de originele pointer krijgt maar de 'pointer + sizeof(int)' ? Iemand enig idee?

EDIT:
na wat lezen in de man lijkt het mij idd duidelijk dat indien men een wrapper maakt voor malloc/free ook calloc en realloc gewrapped moeten worden. Anders zal free niet helemaal meer snappen waar het mee bezig is en zal de kernel je progsel per direct het geheugen uit flikkeren.

[ Voor 12% gewijzigd door Verwijderd op 22-09-2003 12:24 ]


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Verwijderd schreef op 22 september 2003 @ 12:17:
[...]

Zou dit te maken kunnen hebben met eventuele aanroepen van realloc, die dan niet de originele pointer krijgt maar de 'pointer + sizeof(int)' ? Iemand enig idee?
Als je een dergelijke lib maakt lijkt het me wel handig dat je wrappers maakt voor alle mem functies. Dus inclusief realloc() calloc() etc.

All my posts are provided as-is. They come with NO WARRANTY at all.

Pagina: 1