Last active
August 29, 2015 13:56
-
-
Save hashier/9317235 to your computer and use it in GitHub Desktop.
Blocks on stack and on the heap and pointers to it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
int main(int argc, char *argv[]) { | |
@autoreleasepool { | |
typedef int(^Block)(void); | |
void *p0, *p1; | |
Block blockOnStack[3]; | |
Block blockOnHeap [3]; | |
for (int i=0; i<3; i++) { | |
int int1 = 5; | |
int int2 = 10; | |
Block closure = ^{ return i; }; | |
blockOnStack[i] = closure; | |
blockOnHeap [i] = Block_copy( closure ); | |
printf("closure pointer: %p\n", blockOnStack[i] ); | |
printf("Block_copy pointer: %p\n", blockOnHeap [i] ); | |
} | |
printf("\nExecuting blocks from the stack\n"); | |
for (int i = 0; i < 3; i++) { | |
printf("pointer b[%d]: %p\n", i, blockOnStack[i] ); | |
printf("Execute b[%d]: %d\n", i, blockOnStack[i]() ); | |
} | |
printf("\nExecuting blocks from the heap\n"); | |
for (int i = 0; i < 3; i++) { | |
printf("pointer b[%d]: %p\n", i, blockOnHeap[i] ); | |
printf("Execute b[%d]: %d\n", i, blockOnHeap[i]() ); | |
} | |
printf("\nC blocks\n"); | |
// "normal" C block scope 1 | |
{ | |
int blockInt0 = 5; | |
p0 = &blockInt0; | |
} | |
// "normal" block scope 2 | |
{ | |
int blockInt1 = 10; | |
p1 = &blockInt1; | |
} | |
printf("p0 = %p\np1 = %p\n", p0, p1); | |
return 0; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Commented output: | |
Every closure that is created inside the | |
for loop is created at the exact same | |
memory location on the stack. | |
The copied closures on the heap all have | |
different pointer addresses | |
closure pointer: 0x7fff54850bf0 | |
Block_copy pointer: 0x7fe5eac07c70 | |
closure pointer: 0x7fff54850bf0 | |
Block_copy pointer: 0x7fe5eac07ca0 | |
closure pointer: 0x7fff54850bf0 | |
Block_copy pointer: 0x7fe5eac07cd0 | |
Stack pointers, all same ^^^^^^^^^^ | |
Heap pointers, all distinct ^^^^^^^^^^^^^^ | |
Executing blocks from the stack | |
pointer b[0]: 0x7fff54850bf0 | |
Execute b[0]: 2 | |
pointer b[1]: 0x7fff54850bf0 | |
Execute b[1]: 2 | |
pointer b[2]: 0x7fff54850bf0 | |
Execute b[2]: 2 | |
Executing blocks from the heap | |
pointer b[0]: 0x7fe5eac07c70 | |
Execute b[0]: 0 | |
pointer b[1]: 0x7fe5eac07ca0 | |
Execute b[1]: 1 | |
pointer b[2]: 0x7fe5eac07cd0 | |
Execute b[2]: 2 | |
C blocks | |
Unlike the for loop C block scopes create a new stack | |
area for every visibility scope. | |
Unless compiled with e.g. gcc -O2 | |
Remember: This is a implementation detail!!! | |
p0 = 0x7fff54850be4 | |
p1 = 0x7fff54850be0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment