sub esp,4*10; Make space on the stackC/C++ of course can't directly access the stack pointer, but there's often a compiler-builtin function called "alloca" (which looks suspiciously like malloc!) that allocates a user-defined amount of space on the stack. Unlike malloc, memory allocated with alloca is automatically freed when the function returns. "alloca" may not exist on all machines, since some machines have rather funky stacks.
mov eax, esp; Point eax to the start of that space
... ; Use eax as array here
add esp,4*10; Restore stack
push 4*10; Number of bytes to allocate(executable NetRun link)
extern malloc
call malloc
add esp,4; Undo "push"
; Malloc's return value, a pointer, comes back in eax.
... ; use eax as array here
; Eventually, you'll need to call "free" to release that memory:
push eax
extern free
call free
add esp,4; Undo "push"
mov eax,thingy; Point eax to thingy's data
...
section .bss; <- Uninitialized (but writeable!) data area
thingy:
resb 4*10; Reserve this many bytes of space here
Allocation Method |
Allocation Speed |
Storage Available |
Assembly Example |
Disadvantages |
malloc/free |
Slow (100ns) |
Gigabytes |
push 100 call malloc |
Must remember to call free |
stack or alloca |
Fast (1ns) |
Megabytes |
sub esp,100 mov eax,esp |
Must remember to move stack pointer back; storage is limited to stack size; alloca() not always available in C/C++ |
"section" |
Not needed (fixed allocation!) |
Megabytes |
mov eax,my_pointer my_pointer: resb 100 |
Wastes space even when not in use; usually not "threadsafe" |
int n=read_input();The problem is this trashes 3*n bytes of heap memory, but if you're "lucky" nobody's using those bytes, and your program survives. It will crash eventually, though, usually after some other code is added/changed. This code only crashes (when the guilty array is freed) once you add some innocent pointer manipulation elsewhere in the program:
int *arr=(int *)malloc(n); /* OOPS! n bytes, not n ints! */
std::cout<<"Arr runs from "<<arr<<" to "<<arr+n<<"\n";
for (int i=0;i<n;i++) arr[i]=i;
iarray_print(arr,n);
std::cout<<"OK, done with arr--freeing it.\n";
free(arr);
int *innocent=(int *)malloc(sizeof(int));You can get an immediate crash on accessing off the end of your memory by linking with "electric fence", a cool little library by Bruce Perens. Just link with "-lefence". On Linux, valgrind is similar but doesn't even require re-linking.
*innocent=3;
std::cout<<"Innocent pointer at "<<innocent<<"\n";
int n=read_input();
int *arr=(int *)malloc(n); /* OOPS! n bytes, not n ints! */
std::cout<<"Arr runs from "<<arr<<" to "<<arr+n<<"\n";
for (int i=0;i<n;i++) arr[i]=i;
iarray_print(arr,n);
std::cout<<"OK, done with arr--freeing it.\n";
free(arr);
if (*innocent!=3) std::cout<<"Innocent bystander shot like moose!(page A3)\n";
std::cout<<"Freeing innocent bystander\n";
free(innocent);
int n=read_input();If you're getting weird crashes in a big C/C++ program, it's quite possible that somebody's overwriting memory! This is one place where the explicit array size checks built into Java or C# really shine--you can't corrupt the heap in those languages, because every array access verifies that the index is in-bounds. Of course, those extra checks can take some time, so those languages can be a bit slower than C++.
int *arr=(int *)malloc(n); /* OOPS! n bytes, not n ints! */
std::cout<<"Arr runs from "<<arr<<" to "<<arr+n<<"\n";
for (int i=0;i<n;i++) arr[i]=i;
iarray_print(arr,n);
std::cout<<"OK, done with arr--freeing it.\n";
free(arr);
class myArray {
int *arr;
int length;
public:
myArray(int n) {
arr=(int *)malloc(n*sizeof(int));
length=n;
}
int & operator[] (int index) {
if (index<0 || index>=length)
{ /* out of bounds! */
std::cout<<"I'm very sorry, but you've gone out of bounds.\n";
std::cout<<" Your index "<<index<<" is more than the array length "<<length<<".\n";
exit(1);
}
return arr[index];
}
};
int n=read_input();
myArray a(n);
a[1]=123;
a[n+1]=1234;
return a[1];