msize() für Linux?

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

msize() für Linux?
Sorry, aber wo ich grad mal in der Stimmung bin…

(Alle, die jetzt absolut SysProg-genervt sind, sollten sich an dieser Stelle besser was anderes zum Lesen suchen!)

Ich war grade dabei, mir ein kleines Shell-Tool zu coden, da merk ich doch sehr schnell wieder, wie umständlichst es nur sein kann, mit [m]char *[/m] Pseudo-Strings zu arbeiten… :frowning: Also musste eine Portierung meiner Win32-CString-Klasse her. Bin jetzt fast fertig, nur hätte ich gerne mal gewusst, ob es unter Linux auch sowas wie die [m]int msize(void *)[/m]-Funktion gibt? Unter Windows gibt die mir die Größe des allokierten Speicherbereichs zurück. Ich könnte jetzt natürlich hergehen und mir bei jedem re|malloc die neue Größe merken, aber so wär’s irgendwie schöner, find ich. Oder nicht? Naja, kennt jemand diese Funktion? Ich find sie irgendwie nicht…


in der malloc manpage ist zumindest kein Verweis auf etwas derartiges deshalb würd ich jetzt einfach mal vermuten dass es sowas nicht gibt… lasse mich aber gern korrigieren :wink:


tja :vogel: was ist dazu zu sagen?

/usr/include/malloc.h

[quote]/* Report the number of usable allocated bytes associated with allocated
chunk __ptr. */
extern size_t malloc_usable_size __MALLOC_P ((__malloc_ptr_t __ptr));
[/quote]

version 2.3.2.ds1-11 von libc6-dev

[code=C]#include <malloc.h>
#include <stdio.h>

int main (void) {
void *ptr = NULL;
size_t size = 0;
int i;

    ptr = malloc (1000);
    size = malloc_usable_size (ptr);

    printf ("size is %d\n", size);

    for (i=0; i<size; ++i)
            *((char *)ptr)=1;

    printf ("nix segfault! ;-)\n");
    return 0;

}
[/code]

testlauf:

[quote]size is 1004
nix segfault! :wink:
[/quote]


hast du auch die libefence benutzt? ohne die krachts sowieso nicht unbedingt, einen segv gibts ja nur, wenn du aus der Seite rauskommst.
ah die Funktion gibts wirklich und sie macht scheinbar auch das was man denkt, dass sie macht. Ist aber nur speziell für linux und auch nicht für diesen Zweck gedacht, sondern eher zu debuggen oder tunen.
@ Ives: Wenn du eh mit Klassen arbeiten willst, kannst du doch da elegant mit new und delete, den STL-Containern oder einfach den vorgefertigten Klassen arbeiten. Was der Unterschied von CString zu String ist weis ich allerdings nicht so genau.


ok in den header hab ich nicht reingeschaut das war mir zu 1337 :wink:


nicht das ich wüsste…

[quote]kabel@kabel:/tmp$ ldd asdf
libc.so.6 => /lib/libc.so.6 (0x40024000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
kabel@kabel:/tmp$
[/quote]

die ist garantiert NICHT linux spezifisch, es kann allerdings sein, dass sie nur in dieser libc definiert ist.
das genaue interface des libc memory allocators wäre allerdings schon mal interessant zu sehen.

[scnr]
im übrigen, wer braucht schon manpages, die header-dateien hätten gereicht :wink:
[/scnr]


Naja, hab noch kein C++ für Linux gelernt… :rolleyes: Ich hab eigentlich keine Ahnung, was es da schon alles gibt. Ich kenn jetzt halt die MFC für Windows, aber ob/dass es sowas ähnliches auch in Linux gibt, hätt ich nicht gewusst. Und new/delete is für den internen char*-Pointer etwas ungeeignet… V.a. ist es einfacher, den allokierten Speicher um n zu vergrößern, wenn ich die aktuelle Größe hab… Naja, Feintuning kommt nächstes Semester, denk ich! Jetzt läuft’s erstmal.

PS: Ist es in heutigen Betriebssystemen eigentlich aufwändig, den Speicher oft um einige Bytes in der Größe zu verändern? (mit re|malloc) Oder sollte ich mich auf nächstgrößere ‚gerade‘ Zahlen beschränken?


[quote=Yves]PS: Ist es in heutigen Betriebssystemen eigentlich aufwändig, den Speicher oft um einige Bytes in der Größe zu verändern? (mit re|malloc) Oder sollte ich mich auf nächstgrößere ‚gerade‘ Zahlen beschränken?
[/quote]

ich habe mal die groesse des allokierten bereiches auf 1000, 10000 und 100000 gesetzt, das programm mit strace aufgerufen und die stderr-ausgabe in entsprechend benamste dateien umgelenkt. ergebnis:

[quote]kabel@kabel:/tmp$ cat 1000
execve(„./asdf“, [„./asdf“], [/* 28 vars */]) = 0
uname({sys=„Linux“, node=„kabel“, …}) = 0
brk(0) = 0x80496a4
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000
access(„/etc/ld.so.nohwcap“, F_OK) = -1 ENOENT (No such file or directory)
open(„/etc/ld.so.preload“, O_RDONLY) = -1 ENOENT (No such file or directory)
open(„/etc/ld.so.cache“, O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=47096, …}) = 0
old_mmap(NULL, 47096, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40018000
close(3) = 0
access(„/etc/ld.so.nohwcap“, F_OK) = -1 ENOENT (No such file or directory)
open(„/lib/libc.so.6“, O_RDONLY) = 3
read(3, „\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200^\1“…, 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1244004, …}) = 0
old_mmap(NULL, 1254244, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40024000
old_mmap(0x4014c000, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x127000) = 0x4014c000
old_mmap(0x40154000, 9060, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40154000
close(3) = 0
munmap(0x40018000, 47096) = 0
brk(0) = 0x80496a4
brk(0x806a6a4) = 0x806a6a4
brk(0) = 0x806a6a4
brk(0x806b000) = 0x806b000
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), …}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40018000
write(1, „size is 1004\n“, 13) = 13
write(1, „nix segfault! ;-)\n“, 18) = 18
munmap(0x40018000, 4096) = 0
exit_group(0) = ?
kabel@kabel:/tmp$ diff 1000 10000
26c26
< write(1, „size is 1004\n“, 13) = 13

write(1, „size is 10004\n“, 14) = 14
kabel@kabel:/tmp$ diff 1000 100000
26c26
< write(1, „size is 1004\n“, 13) = 13


write(1, „size is 100004\n“, 15) = 15
kabel@kabel:/tmp$[/quote]

der effekt dürfte wohl dem libc memory allocator „anzukreiden“ sein.


sorry, ich check da nix von… :confused:
was ist strace überhaupt?


mit strace werden alle systemcalls geloggt und auf stderr ausgegeben.
der aufruf sieht so aus:

in strace.log steht dann das was ich gepostet habe :slight_smile:
und da sich die systemcalls nicht geändert haben (siehe diffs), muss der prozess
diesen speicher also schon reserviert gehabt haben.
sonst würde sich ein brk() aufruf verändert haben!

HTH


Aha, danke! Nagut, dann bleibt mein Programm erstmal so, wie es ist… Ich hab die CString-Klasse irgendwann mal aus den MFC rausgenommen, weil ich sie auch außerhalb davon haben wollte. Ging recht problemlos, musste gar nicht mal soviel dran ändern.


ähm ja Wieso sollte es denn die STANDART-c+±Laufzeitbibiothek unter linux nicht geben?


Weiß denn ich, dass da schon tausende Klassen vordefiniert sind? Sowas wie MFC (was unter Windows der ‘minimale’ Standard ist, und ja schon fast .NET-Ausmaße hat) hab ich nicht erwartet.


Ich war auch sehr erstaunt, dass unter Windows die BUSN-Klasse nicht dabei ist. Ich brauch dringend einen plattformübergreifenden Wrapper für unidirektionale BUSN-Sockets.