Compilers way to implement array allocations

C

crea

I have been thinking, that does anybody know what is the difference in
machine code between normal array memory allocation:

int some_array1[10];

compared to dyanamical allocation:

int* some_array2 = new int[10];

I mean, what does the compiler do to know that in the first case the memory
cannot be deleted using "delete" and in the second one delete can be done?

In the first case the memony is allocated "permanently"...Is there just
somekind of "flag" by which the probram defines that the some_array1 is a
"fixed" memory? What is the dirrennce between compiling some_array1 and
some_array2 (in machine code level)?
 
G

Goran

I have been thinking, that does anybody know what is the difference in
machine code between normal array memory allocation:

int some_array1[10];

compared to dyanamical allocation:

int* some_array2 = new int[10];

I mean, what does the compiler do to know that in the first case the memory
cannot be deleted using "delete" and in the second one delete can be done?

Compiler will happily allow you to write "delete some_array;" (or
"delete [] some_array"), but doing so is undefined behavior. IOW...
This is completely out of compiler's hands.

You should also note that ::eek:perator delete (global one) receives a
void* and is consequently rather underwhelming.

When you call operator delete yourself, you need to pass it a pointer
to some type. You can't ever pass it "an array", because AFAIK, in
order for an array to go into any function/operator, it's first
converted to a pointer to it's first element.

When you call operator delete, it calls destructor of the object, then
deallocates storage (this is why ::eek:perator delete is less
interesting: it can't know what destructor to call. When you call
operator[] delete, it calls as many destructors as objects allocated
by the corresponding call to operator new[]. Manner used to allocate
storage in new must match the manner to deallocate storage in delete
(important when you overload new/delete).
In the first case the memony is allocated "permanently"...Is there just
somekind of "flag" by which the probram defines that the some_array1 is a
"fixed" memory?  What is the dirrennce between  compiling some_array1and
some_array2 (in machine code level)?

There's no flag. It's the duty of the code not to mix things up;
dragons await if it does mix them. That said... There are three
"storage classes" in C and C++:

static (objects that exist for the whole program duration; you declare
them outside any function, or as static class members; their lifetime
is in hands of the compiler)

automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)

dynamic (objects allocated/deallocated with new/delete or free/malloc
for C; these are placed into free store, or heap, and their lifetime
is in hands of the code - they are destroyed when code calls operator
delete on a corresponding pointer).

Finally, there's function-static objects, as in void f() { ... static
int i; ...} I don't know how they are classified.

Goran.
 
V

Victor Bazarov

[...] There are three
"storage classes" in C and C++:

static (objects that exist for the whole program duration; you declare
them outside any function, or as static class members; their lifetime
is in hands of the compiler)

automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)

Class members have the same storage duration as the object to whom they
belong.
dynamic (objects allocated/deallocated with new/delete or free/malloc
for C; these are placed into free store, or heap, and their lifetime
is in hands of the code - they are destroyed when code calls operator
delete on a corresponding pointer).

Finally, there's function-static objects, as in void f() { ... static
int i; ...} I don't know how they are classified.

What do you mean, you don't know? They are just as static as the other
ones. Their storage is allocated at the beginning of the program, and
zero-initialized, and they are destructed at the end of the program, in
the reverse order of their initialization.

V
 
C

crea

"automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)"

So my question is, that why cant I destroy this automatic object? How/why
does the compiler prevent that? Is is located at a specific memory part
where computer does not accept reallocation?

Or in theory I could delete it, but the compiler prevents it because it
knows its defined as "automatic" when it compiled it? so its amatter of
definition....
 
V

Victor Bazarov

"automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)"

So my question is, that why cant I destroy this automatic object? How/why
does the compiler prevent that? Is is located at a specific memory part
where computer does not accept reallocation?

To answer in the order: no reason, go ahead and destroy it. The
compiler does not even try to prevent that. It is usually allocated in
the "data segment", the portion commonly known as "stack".

There is a catch, however. If you do try to delete (or delete[]) a
pointer that you didn't get from 'new' (or 'new []'), the code has
*undefined behaviour*. Anything can happen. There is no telling *what*
will happen. Not to mention that next time you do it, some *other*
thing can happen (no predictability whatsoever). Read up on undefined
behaviour.
Or in theory I could delete it, but the compiler prevents it because it
knows its defined as "automatic" when it compiled it? so its amatter of
definition....

Stop asking and do it already! Chicken? <g>

V
 
C

crea

Paavo Helde said:
crea said:
"automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)"

So my question is, that why cant I destroy this automatic object?
How/why does the compiler prevent that? Is is located at a specific
memory part where computer does not accept reallocation?

When you delete a dynamically allocated object, the corresponding memory
is
marked as free in the memory management data structures and can be reused
again.

OTOH, an automatic array as in your example resides on the stack. There
are
no memory management data structures on the stack, so there is nothing
what
delete[] could do. The stack memory just gets "freed" when the stack
pointer moves back when returning from the function. So there is really no
way to "free" the stack memory before that moment.

so its different kind/type of memory
 
G

Goran

What do you mean, you don't know?  They are just as static as the other
ones.  Their storage is allocated at the beginning of the program, and
zero-initialized, and they are destructed at the end of the program, in
the reverse order of their initialization.

I said "I don' know" because they are constructed when code passes
through the code first passes through their initializer, whereas other
statics are initialized before main.

Goran.
 
G

Goran

"automatic (objects that exist in a scope; you declare them inside a
code block, {here}; perhaps class members count as automatic, I am not
sure; their lifetime is in hands of the compiler, too)"

So my question is, that why cant I destroy this automatic object? How/why
does the compiler prevent that?

Compiler does not prevent it. For example:

void f()
{
int i; // automatic
int* p = &i;
delete p; // boom
}

This code is 100% legal, and compiler will compile it without any
complaint. But at runtime, boom!

IOW... Your very question is wrong. Compiler does not prevent anyone
from deleting pointers to automatic/static objects. Code must not do
it.

Note this: you say "why cant I __destroy__ (emphasis mine) this
automatic object". What you mean, rather, is "why can't I __delete__ a
pointer to an automatic object". "Destruction" normally means invoking
a destructor on an object. "Deletion" normally means "destruction
+storage deallocation" (for objects on dynamic storage).
Is is located at a specific memory part
where computer does not accept reallocation?

Automatic objects are normally on the stack (I don't know whether
language specifies what "stack" is, so what I am saying is most likely
implementation-specific, but extremely common), and yes, these are
"specific" memory parts. Most notably, pointers given to you by
operator new do not point into stack. I don't know what you mean by
"reallocation", though, but I am guessing that this is 100% orthogonal
to your initial question.

Goran.
 
C

crea

Ok, i got this stack thing..

So basically: In theory I can destroy that memory but its "illegal" and its
not meant to be destroyed... so the computer crashes. So "we dont delete "
that memory.
 
J

James Kanze

I have been thinking, that does anybody know what is the difference in
machine code between normal array memory allocation:
int some_array1[10];
compared to dyanamical allocation:
int* some_array2 = new int[10];
I mean, what does the compiler do to know that in the first
case the memory cannot be deleted using "delete" and in the
second one delete can be done?

The compiler knows nothing about this. In the first case, the
compiler knows it has created an array of 10 ints, with auto (or
maybe static) lifetime, so it knows when their lifetime ends.
In the second case, the compiler knows it has created a scalar
pointer, with auto (or maybe static) lifetime, so it knows when
its lifetime ends. The fact that you have used a new expression
to initialize this pointer is completely irrelevant to the
compiler; anything you allocate using a new expression is your
business.
In the first case the memony is allocated "permanently"...

Not necessarily. In both cases, you have defined a variable (in
one case, with type int[10], and in the other with type int*).
Depending on where that variable was defined, it has auto or
static lifetime, and the compiler will deal with it when its
lifetime ends.
Is there just somekind of "flag" by which the probram defines
that the some_array1 is a "fixed" memory? What is the
dirrennce between compiling some_array1 and some_array2 (in
machine code level)?

No flag. The compiler knows the lifetime of the variables
internally, and generates whatever code is necessary to
terminate their lifetime when they go out of scope. (In the
case of both int[10] and int*, this code is typically nothing;
neither has a non-trivial destructor which must be executed, and
memory is generally recoverd using other mechanisms when leaving
scope.)
 
J

James Kanze

[...]
So my question is, that why cant I destroy this automatic
object? How/why does the compiler prevent that?
Compiler does not prevent it. For example:
void f()
{
int i; // automatic
int* p = &i;
delete p; // boom
}
This code is 100% legal, and compiler will compile it without any
complaint. But at runtime, boom!

The code is not "legal" (for the usual definition of legal). It
has undefined behavior. One possible behavior is that the
compiler refuse to compile it, or issues an error message.
Another is that something strange happens at runtime.

[...]
Automatic objects are normally on the stack (I don't know whether
language specifies what "stack" is, so what I am saying is most likely
implementation-specific, but extremely common), and yes, these are
"specific" memory parts.

The language doesn't speak directly of a stack, but the
lifetimes of such objects does obey stack semantics, so putting
them on a stack is an obvious implementation solution. (I have
seen a C implementation where the compiler used the equivalent
of malloc to get each stack frame. A long long time ago, and it
has serious performance problems. But the implementation is
clearly legal.)
Most notably, pointers given to you by operator new do not
point into stack. I don't know what you mean by
"reallocation", though, but I am guessing that this is 100%
orthogonal to your initial question.

It might be worth pointing out that when local variables do go
out of scope, the memory they occupy will be reused by other
variables.
 
V

Virchanza

What do you mean, you don't know?  They are just as static as the other
ones.  Their storage is allocated at the beginning of the program, and
zero-initialized, and they are destructed at the end of the program, in
the reverse order of their initialization.


If the function never gets called, the object never gets constructed
nor destructed.

If the function does get called, the object is constructed the first
time the function is called, and destroyed at the end of the program.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top