What's the size of a reference on the CLR - clr

I was (purely out of curiosity) trying to find out what the size of an actual reference is when an allocation is made on the stack.
After reading this I still don't know (this answers it only for value types or type definitions), and I still cannot seem to find it anywhere.
So basically imagine a class as follows
class A
{
string a;
}
Now when an object of type A is instantiated, a reference to the string object would be stored on the stack, now what would the size of the allocation on the stack be?
Disclaimer: If I'm talking complete and utter nonsense please let me know :)

Just like the size of pointers, presumably, the size would be that of a native int: 32-bits on 32-bit platforms and 64-bits on a 64-bit platform.

It will be the size of IntPtr, either 32 or 64 bits, depending upon your environment.

Now when an object of type A is instantiated, a reference to the string object would be stored on the stack, now what would the size of the allocation on the stack be?
The string reference would in fact be stored on the heap, not the stack, since A is a reference type.

Related

How much memory does null value take up in dart VM?

Just started learning coding, get curious how much memory takes null value in dart programming language?
I knew that in java 'null value' takes 4 bytes of memory.
One pointer, just like every other object reference.
The object itself likely takes a little memory somewhere, but every reference to it, the thing you probably mean by "null value", is just a reference to that one object.
The size of a reference/pointer depends on whether the runtime is using 32-bit or 64-bit pointers.

local and dynamic allocating

I have a tree and I want to release the allocated memory, but I face a problem that a pointer may refers to a variable that isn't dynamically allocated,so how to know wether this pointer refers to dynamic a variable or not
This is compiler-specific. You may compare given pointer with pointer to a local variable. Result interpretation depends on the way compiler implements heap and stack. Generally, for given compiler, stack pointer is always less (or greater) than heap pointer.
In any case, THIS IS BAD DESIGN.
This may not work if pointer belongs to another heap (for example, allocated in another Dll).

what is the difference between small memory model and large memory model?

what difference does it make when i choose 'large memory model' instead of 'small memory model' inside Turbo C compiler ?
how does that change behavior of my program ?
regards,
essbeev.
It refers to very old concept of 16-bit memory model. 32bit & 64bit computers know nothing about these memory models.
So returning to your questions: small - declares that pointers allows you address only 64k of data or code. Pointer has length 16 bit. Entire your program is resided in single 64k segment. To explicitly address another part of memory you need explicitly declare pointer as FAR. large - declares that pointer to code or data has 32 bit, so it is FAR by default.
Hope you would not hang on these questions so long, since it is obsolete concept.
The 8086 processor has 20-bit physical addressing using a combination of 16-bit segment register and 16-bit offset. You could pack both into a 32-bit FAR pointer, or you could asssume a default segment register and store just the lower 16 bits in a NEAR pointer.
The difference between the small and large models is simply whether pointers are by default NEAR or FAR when not explicitly specified.

Is it possible to get the size of the type that a pointer points to in Delphi 7?

I want to get the size of any "record" type in following function. But seems it doesn't work:
function GetDataSize(P : Pointer) : Integer;
begin
Result := SizeOf(P^); // **How to write the code?**
end;
For example, the size of following record is 8 bytes
SampleRecord = record
Age1 : Integer;
Age2 : Integer;
end;
But GetDataSize(#a) always returns 1 (a is a variable of SampleRecord type of course). What should I do?
I noticed that Delphi has a procedure procedure New(var P: Pointer) which can allocate the memory block corresponds to the size of the type that P points to. How can it gets the size?
The reason New knows how much memory to allocate is that New is compiler magic. It's a language built-in, so when the compiler sees you call it, it rewrites it to something like this:
// New(foo);
foo := System._New(SizeOf(foo^), TypeInfo(TypeOf(foo^)));
TypeOf here is a made-up Delphi function for expository purposes. The compiler knows the declared type of foo because it knows where all your variable declarations are. You can look at the implementation of _New in System.pas. Similar rewriting occurs for Dispose so it knows what kind of finalization to do before freeing the memory.
The ideas of variables and declarations are compile-time concepts. At run time, they cease to exist. At run time, a pointer is just an address. The type of what it points to was determined at compile time. Types are what determine something's size.
If you need to write a function that accepts pointers to multiple things with different sizes, then you'll just have to provide a second parameter that describes what the first one points to.
Check out another question here, "How to know what type is a var." The asker wondered how to determine more information about a variable given only its address.
You cannot find the size of data structure using variable of type Pointer, because compiler cannot, make a guess and check it, since pointer can points to whatever data type you can think of. You can read some information here.
There's no safe way to determine the size of a record that a pointer points to. However, if you allocated the memory that the pointer points to, you can ask the size of that memory block. But then again, since you allocated that block, you should already know the size of that block!
The Delphi memory manager keeps track of every block of memory that gets allocated. With information from the memory manager it is possible to find this information, if your pointer points to the beginning of a memory block. However, if you allocated a large block of memory, loaded some data in it and your pointer points to some data inside this block, this method would be quite unreliable.
Also, if you use referenced types (dynamic arrays, strings, classes, etc.) in your record, the size it returns will still be unusable since you get the size of the reference (4 bytes) instead of the size of the data that is referenced to.
The NEW() command just uses the type information of the datatype that you pass to it to get it's size. To know how it does this exactly, you could just check the Delphi sourcecode. Open \source\Win32\rtl\sys\System.pas and search for "_New". (With the underscore in front of it. Using this sourcecode might help you to understand how Delphi handles memory allocations, although the sourcecode can be really complex.
Delphi has a built-in memory manager. I believe new has access to the heap object and uses HeapSize() (or similar routines) to get the size of a block, for some pointer.

Byte size of object including size of members

I want to know (for debugging and logging) the size of an object in bytes, but not like
Sizeof (Object)
but like a 'deep sizeof'. For example if the object contains a hash map or a list, the real size needed by that hash map or list should be added to the result. Is there any way to do this without having to add a
property Size : LongWord read GetByteSize;
to each and every little object?
Probably a stupid question, but I'll give it a try ;)
EDIT: Just found almost the same question:
Recursive Class Instance Size in Delphi
I guess, the question can be closed. Sorry about that!
Unfortunately, you need to write the code for this yourself.
Not sure of this works, but you can become very dirty:
Find the object size in bytes. Using TObject.InstanceSize.
Cast each group of 4 bytes to a pointer and then check if it is a TObject. You should be able to do that. If it is a TObject, you should repeat the step.
Since this is for debugging, have you looked at the FastMM4 memory allocator? It's got some nice stuff for tracing memory leaks.

Resources