Can someone explain to me how computer memory allocation works?

Flux

Regular
Can someone explain to me how computer memory allocation works?

If you have a bitset in c like...

bitset something<1>

and

bitset somewhere<10>

How does the computer and the compiler know when one bit ends and another bit begins?
How is data stored in memory without one value overwriting another?

I would assume this is the reason why out of bound arrays can crash a program or cause fatal errors.

Thank you for responding.
 
The byte is your atom, you don't have anything smaller.
You have memory addresses, for exemple 3 would be the 4th byte, 5 the 6th and so on... (You start at 0 but zero is "special", it's not usable it means not set/invalid.)

You use some of your memory to store the memory ranges you have allocated, so you don't allocate the same area later.
[Doesn't prevent a program from writing where it shouldn't, just guarantees that when it asks for memory it is provided with an unused area.]

That's about it for the general view, going into details it gets a lot more complicated because of virtualization and performance, but that general view should be enough to get a broad understanding.
 
In C, if you're ever not sure what a program is doing it's worth trying to think what the assembly code underneath is doing - it's such a close mapping and if you know any assembly a lot of it becomes straight forwards.


How does the computer and the compiler know when one bit ends and another bit begins?
How is data stored in memory without one value overwriting another?

Basically, the address of every variable is stored and you read a number of bytes from that address defined by the type. When you do something like:

int i = (int)myInteger;

It looks up the address of myInteger as a start point. It then loads the data for that integer which the program tells it is an integer = 4 bytes = 32 bits. It stores the result at the address of i which itself is an integer = 4 bytes = 32 bits. Had it been a char it would have read 1 byte = 8 bits, etc.

I would assume this is the reason why out of bound arrays can crash a program or cause fatal errors.

Yes - the whole system relies on two things:

1) that the types you've provided it which define how many bytes/bits are in the value at that address are correct. You can mess this up by something as simple as passing a long to an int or as you say reading the 4th value from a 3 value array. You will probably get a value back (unless you're using a good debugger) but you'll just get whatever happens to be next to it in memory. A mechanism often used for exploiting programs - if you know what the number next to you is for you can read it or modify it using this technique.

2) Your memory hasn't been trashed by writing data to the wrong address. eg: if you had 2 integers stored one after another (4 byte gap) but someone wrote an 8 byte value onto the first integer you'd have destroyed the value in the second integer.
 
theres also a null terminated string
where the end of the string is dented by a null character as used in c
or the Length-prefixed string where the string starts with a number denoting its length as used in pascal

also the mistakes pix mentioned should never really happen the compiler should never let you pass a long to an int you should get a type mismatch error within the compiler
also a compiler shouldnt let you go out of bounds in an array. but i'm sure many do C will happily give you enough rope to hang yourself.
 
As Simon says - these happen all the time in C/C++ - warnings aren't a requirement (although you do tend to get them in Visual Studio/gcc if your warning level is high enough and you have fail on warnings enabled).

Compilers can't stop you going out of bounds in an array if you access it with a pointer. Runtime code analysis or a tool like Valgrind configured to spot these issues will usually stop you but compilers don't do a good job with this because you're allowed to do it in the language (and it's useful if you know what you're doing).

To be honest I over simplified. It's a base address and a type. Null termination is a good one though as it's a very common way of handling variable length data I forgot about. :)
 
Which is what the strict (er switch/compiler directive) is for is it not
to stop you doing silly things
and why isnt it compulsory

It's not compulsory because sometimes you want to do it... It's simply not practical/convenient /optimal in some cases to deal efficiently with strict typing. At the end of the day your memory is just a big bit bucket, and sometimes it's useful to deal with it that way.

Even what appear to be safe languages have similar issues, it's no different than casting an object to another class in say java and expecting it to be correct, sure you can catch the exception, but that's no guarantee your program can deal with the failure.

Mismatched pointer types IME are rarely a major issue because if you are doing it, you are usually aware of it, now bad array indices, bad pointer math, unhandled null pointers are a different story.

GCC's pointer aliasing warnings and the optimizations it does that aren't valid with pointer aliasing are really annoying in some cases. The standard even allows for aliasing of char pointers so you can work around it.
 
reinterpret_cast and void* are good friends to low level programmers. (although many prefer C style cast, it's less visible IMO.)

Did we answer Flux question well enough though ?
 
That's why I like this forum. You have a lot of people that really know what they are talking about and give you a very educational answer.


Thank you very much for responding.
 
Back
Top