Evgenios1 Δημοσ. 13 Νοεμβρίου 2009 Δημοσ. 13 Νοεμβρίου 2009 Μετα απο αρκετο πειραματισμο για να καταλαβω πως στο καλο κανει deallocate η free, δηλαδη πως στο καλω ξερει ποσα byte να "κανει dealloc". Ανακαλυψα καποια extra info που συνοδεβονται με το pointer που σου δινει η malloc (ενας θεος ξερει πως τα βρηκα ). πχ για να δω το μεγεθος ενος buffer κανω το παρακατω >// alloc test23.cpp : Defines the entry point for the console application. // #include "stdafx.h" size_t buflen(void *p); int _tmain(int argc, _TCHAR* argv[]) { int *a =(int*) malloc(8); char *b = (char*) malloc(1234567); printf("A size:%d\nB size:%d\n",buflen(a),buflen(); free(a); free(; getchar(); return 0; } size_t buflen(void *p) { return *((size_t*)((char*)p-16)); } Το ερωτημα μου ειναι, εαν ειναι standar το παραπανω, για ποιο λογο οταν εχουμε συναρτηση με pointer πρεπει να βαλουμε και το μεγεθος, εφοσον μπορουμε να το παρουμε με το παραπανω τροπο? Και δευτερο, τι εχουν τα 12 byte πριν τον pointer? Υγ: τα παραπανω ισχυει και για το new.
bxenos Δημοσ. 13 Νοεμβρίου 2009 Δημοσ. 13 Νοεμβρίου 2009 όχι δεν είναι standard. H ομάδα [mc]alloc αλλά και η new, κάθε φορά που δεσμεύεις μνήμη, δεν ζητάνε απο το λειτουργικό μνήμη. Δηλαδή: γίνεται η πρώτη αίτηση μνήμης με malloc. Η c-rtl ζητά απο το λειτουργικό ένα μεγαλύτερο αρκετά κομάτι μνήμης (π.χ. 64Kbytes) και σωζει σε μια λίστα την αναφορά σε αυτό. Απο το κομάτι που έχει δεσμευσει, πέρνει ένα κομάτι (ισως το πρωτο ελευθερο) και αφου γράψει ένα header (για να ξέρει τι έδωσε), σου το δείνει (εσυ βρήκες ένα απο τα στοιχεια του header). Την επόμενη φορά θα χρησιμοποιήσει τον προηγουμενα δεσμευμένο ελεύθερο χωρο (αν δεν υπάρχει θα κάνει εκ νεου δεσμευση απο το λειτουργικο). Ουτε η σειρά με την οποια θα επαναχρησιμοποιηθούν τα ελευθερωμενα κοματια μνημης με free/delete είναι standard. Υπάρχουν πολλές μέθοδοι (π.χ best fit,worst fit, first fit,...). Τι θα κερδίσεις αν ξέρεις τα στοιχεία αυτά; Αν θέλεις λεπτομερη έλεγχο (για π.χ. debugging) κάνεις το δικό σου memory allocation συστημα. To new/delete καλεί malloc ίσως σε όλες τις υλοποιήεις (δεν είναι δεσμευτικό). Σε debug compile μπορεί να υπάρχουν περισσότερα bytes (με κάποια fillers) ώστε αν γράψεις κατα λαθος περισσότερο χωρο απο οτι εχεις να βγει προειδοποιηση
Evgenios1 Δημοσ. 14 Νοεμβρίου 2009 Μέλος Δημοσ. 14 Νοεμβρίου 2009 1) Εχεις κανα λινκ που να τα λεει αυτα ( ή τι να βαλω στο google για να βρω σχετικο πραμα) 2) Υπαρχει τροπος να παρω την κανονικη address ? (κατι σαν mem debug) Υγ: Βρηκα ενα ppt για αυτο που λες "best fit first fit etc" μου φανηκε αρκετα ενδιαφερον, μονο που δεν καταλαβαινω πως θα εχω ενα array απο ακυρους pointers .
ippo00 Δημοσ. 14 Νοεμβρίου 2009 Δημοσ. 14 Νοεμβρίου 2009 2) άν καταλαβαίνω τι ρωτάς ξέκινα από το wikipedia να διαβάσεις τι είναι virtual memory επεξεργασία: υποθέτω το ένα θα οδηγήσει στο άλλο και θα διαβάσεις για memory segmentation, free lists κτλπ
bxenos Δημοσ. 14 Νοεμβρίου 2009 Δημοσ. 14 Νοεμβρίου 2009 δεν ξέρω αν υπάρχει σελίδα που να περιγράφει π.χ. τις microsoft crtl memory allocation structures. Γιατί όπως είπα δεν είναι standard η μέθοδος σε όλες τις υλοποιήσεις... αλλά θα κοίταγα πρώτα εδώ (υπάρχουν τα header structs και τα bitfields αλλα δεν έχει τα handles του λειτουργικού συστηματος) > /*** *malloc.h - declarations and definitions for memory allocation functions * * Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: * Contains the function declarations for memory allocation functions; * also defines manifest constants and types used by the heap routines. * [system V] * * [Public] * ****/ #if _MSC_VER > 1000 #pragma once #endif #ifndef _INC_MALLOC #define _INC_MALLOC #include <crtdefs.h> #ifdef _MSC_VER /* * Currently, all MS C compilers for Win32 platforms default to 8 byte * alignment. */ #pragma pack(push,_CRT_PACKING) #endif /* _MSC_VER */ #ifdef __cplusplus extern "C" { #endif /* Maximum heap request the heap manager will attempt */ #ifdef _WIN64 #define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0 #else #define _HEAP_MAXREQ 0xFFFFFFE0 #endif /* _STATIC_ASSERT is for enforcing boolean/integral conditions at compile time. */ #ifndef _STATIC_ASSERT #define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr) ] #endif [color="Red"][b]/* Constants for _heapchk/_heapset/_heapwalk routines */ #define _HEAPEMPTY (-1) #define _HEAPOK (-2) #define _HEAPBADBEGIN (-3) #define _HEAPBADNODE (-4) #define _HEAPEND (-5) #define _HEAPBADPTR (-6) #define _FREEENTRY 0 #define _USEDENTRY 1 #ifndef _HEAPINFO_DEFINED typedef struct _heapinfo { int * _pentry; size_t _size; int _useflag; } _HEAPINFO; #define _HEAPINFO_DEFINED #endif [/b] [/color]/* External variable declarations */ _Check_return_ _Ret_bytecap_(_Size) void * __cdecl _alloca(_In_ size_t _Size); _Check_return_ _CRTIMP size_t __cdecl _get_sbh_threshold(void); _CRTIMP int __cdecl _set_sbh_threshold(_In_ size_t _NewValue); _CRTIMP errno_t __cdecl _set_amblksiz(_In_ size_t _Value); _CRTIMP errno_t __cdecl _get_amblksiz(_Out_ size_t * _Value); _Check_return_ _CRTIMP int __cdecl _heapadd(_In_ void * _Memory, _In_ size_t _Size); _Check_return_ _CRTIMP int __cdecl _heapchk(void); _Check_return_ _CRTIMP int __cdecl _heapmin(void); _CRTIMP int __cdecl _heapset(_In_ unsigned int _Fill); _CRTIMP _CRT_MANAGED_HEAP_DEPRECATE int __cdecl _heapwalk(_Inout_ _HEAPINFO * _EntryInfo); _CRTIMP size_t __cdecl _heapused(size_t * _Used, size_t * _Commit); _CRTIMP intptr_t __cdecl _get_heap_handle(void); #define _ALLOCA_S_THRESHOLD 1024 #define _ALLOCA_S_STACK_MARKER 0xCCCC #define _ALLOCA_S_HEAP_MARKER 0xDDDD #if defined(_M_IX86) #define _ALLOCA_S_MARKER_SIZE 8 #elif defined(_M_IA64) #define _ALLOCA_S_MARKER_SIZE 16 #elif defined(_M_AMD64) #define _ALLOCA_S_MARKER_SIZE 16 #endif _STATIC_ASSERT(sizeof(unsigned int) <= _ALLOCA_S_MARKER_SIZE); #if !defined(__midl) && !defined(RC_INVOKED) #pragma warning(push) #pragma warning(disable:6540) __inline void *_MarkAllocaS(_Out_opt_ __crt_typefix(unsigned int*) void *_Ptr, unsigned int _Marker) { if (_Ptr) { *((unsigned int*)_Ptr) = _Marker; _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE; } return _Ptr; } #ifdef HEAPHOOK #ifndef _HEAPHOOK_DEFINED /* hook function type */ typedef int (__cdecl * _HEAPHOOK)(int, size_t, void *, void **); #define _HEAPHOOK_DEFINED #endif /* _HEAPHOOK_DEFINED */ /* set hook function */ _CRTIMP _HEAPHOOK __cdecl _setheaphook(_In_opt_ _HEAPHOOK _NewHook); /* hook function must handle these types */ #define _HEAP_MALLOC 1 #define _HEAP_CALLOC 2 #define _HEAP_FREE 3 #define _HEAP_REALLOC 4 #define _HEAP_MSIZE 5 #define _HEAP_EXPAND 6 #endif /* HEAPHOOK */ #ifdef __cplusplus } #endif #ifdef _MSC_VER #pragma pack(pop) #endif /* _MSC_VER */ #endif /* _INC_MALLOC */ Reverse engineering: αν ήθελα να το βρώ σε μια συγκεκριμένη (άγνωστη) υλοποίηση, τον τρόπο που δεσμεύει μνήμη η malloc, θα ξεκίναγα με α) debugger και dump της μνήμης για τα σημεία που αλλάζουν σε ένα test προγραμμα που θα έκανα... κάπου θα ενημερώνεται η linked list με τα allocated blocks (οι pointers θα είναι στο header του μπλόκ που σου επέστρεψε η malloc) και κάπου θα υπάρχει ο memory handler απο το λειτουργικό σύστημα... Στο header περιμένω να υπάρχει pointer για το προηγούμενο block, για το επόμενο, για την κατάσταση (bitfields) και το μέγεθος του τρέχοντος. β) Στα windows μπορείς να χρησιμοποιήσεις και hooks (π.χ.) για να κάνω log διευθύνσεις... ---------- Το μήνυμα προστέθηκε στις 10:28 ---------- Δες και εδώ (τα structs/calls του malloc.h): α ---------- Το μήνυμα προστέθηκε στις 10:33 ---------- και άλλες ανησυχίες
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.