4

This one has been bothering me for a while now: Is there a difference (e.g. memory-wise) between this

Pointer *somePointer;
for (...)
{
    somePointer = something;
    // do stuff with somePointer
}

and this

for (...)
{
    Pointer *somePointer = something;
    // do stuff with somePointer
}
fabian789
  • 8,348
  • 4
  • 45
  • 91
  • Tighter variable scope uses less memory, and is one reason to avoid global variables. – Alex Reynolds Feb 19 '11 at 17:52
  • I feel this is a matter of the habit of a programmer! Someone like to declare a variable before using it(probably make your program more logical); someone like to define the variable when first using it( thats what your second loop does). – Rn2dy Feb 19 '11 at 18:01
  • @baboon the first one doesn't come from making it more logical. If anything, declaring variables in proper scope, before their usage, is more logical. Declaring them upfront comes from languages where the compiler required you to declare them all up front, and some programmers just haven't caught up with the times. – corsiKa Feb 19 '11 at 18:04
  • @Alex with optimization on, the memory use between those two is irrelevant (and identical). Globals are an entirely different beast. – bbum Feb 19 '11 at 19:09
  • Isn't it better to allocate the pointer's memory just once instead of every single time within the for loop? – sudo May 15 '14 at 00:15

4 Answers4

4

If you want to use the pointer when you're done with the loop, you need to do the first one.

Pointer *somePointer;
Pointer *somePointer2;
for(loopA)
{
    if(meetsSomeCriteria(somePointer)) break;
}

for(loopB)
{
    if(meetsSomeCriteria(somePointer2)) break; 
}
/* do something with the two pointers */
someFunc(somePointer,somePointer2);
bbum
  • 162,346
  • 23
  • 271
  • 359
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • @bbum - While I won't contest the edit, I question the necessity of it. I guess it's a matter of preference whether you'd rather get a pointer or a reference as your parameter. Are there significant implications otherwise? – corsiKa Feb 19 '11 at 19:49
  • Sorry -- I mean to comment with an explanation. The question was tagged `objective-c` and `Pointer*` would almost assuredly be a pointer to an instance of the class. Thus, `*somePointer` would be incorrect 99% of the time. Non-stack C structures just aren't seen often in Cocoa/iOS. – bbum Feb 19 '11 at 19:55
3

Well, first, in you second example somePointer will be valid only inside the loop (it's scope), so if you want to use it outside you have to do like in snippet #1.
If we turn on assembly we can see that the second snipped needs only 2 more instructions to execute:

Snippet 1:

for(c = 0; c <= 10; c++)
    (*p1)++;  

0x080483c1 <+13>:   lea    -0x8(%ebp),%eax          # eax = &g
0x080483c4 <+16>:   mov    %eax,-0xc(%ebp)          # p1 = g
0x080483c7 <+19>:   movl   $0x0,-0x4(%ebp)          # c = 0
0x080483ce <+26>:   jmp    0x80483e1 <main+45>      # dive in the loop
0x080483d0 <+28>:   mov    -0xc(%ebp),%eax          # eax = p1
0x080483d3 <+31>:   mov    (%eax),%eax              # eax = *p1
0x080483d5 <+33>:   lea    0x1(%eax),%edx           # edx = eax + 1
0x080483d8 <+36>:   mov    -0xc(%ebp),%eax          # eax = p1
0x080483db <+39>:   mov    %edx,(%eax)              # *p1 = edx
0x080483dd <+41>:   addl   $0x1,-0x4(%ebp)          # c++
0x080483e1 <+45>:   cmpl   $0xa,-0x4(%ebp)           # re-loop if needed
0x080483e5 <+49>:   jle    0x80483d0 <main+28>

Snippet 2:

for(c = 0; c <= 10; c++) {
    int *p2 = &g;
    (*p2)--;
}
0x080483f0 <+60>:   lea    -0x8(%ebp),%eax          # eax = &g
0x080483f3 <+63>:   mov    %eax,-0x10(%ebp)         # p2 = eax
0x080483f6 <+66>:   mov    -0x10(%ebp),%eax         # eax = p2
0x080483f9 <+69>:   mov    (%eax),%eax              # eax = *p2
0x080483fb <+71>:   lea    -0x1(%eax),%edx          # edx = eax - 1
0x080483fe <+74>:   mov    -0x10(%ebp),%eax         # eax = p2
0x08048401 <+77>:   mov    %edx,(%eax)              # *p2 = edx
0x08048403 <+79>:   addl   $0x1,-0x4(%ebp)          # increment c
0x08048407 <+83>:   cmpl   $0xa,-0x4(%ebp)          # loop if needed
0x0804840b <+87>:   jle    0x80483f0 <main+60>

Ok, the difference is in the first two instructions of snippet #2 which are executed at every loop, while in the first snippet they're executed just before entering the loop.
Hope I was clear. ;)

BlackBear
  • 22,411
  • 10
  • 48
  • 86
  • You compiled this without optimization. If you turn optimizations on using any reasonable compiler, you will find that the code generated is identical (and that both loops are eliminated entirely and replaced by a simple add/subtract of 11). – Stephen Canon Feb 19 '11 at 18:28
  • @Stephen Canon: Of course, but I wanted to show that there's no substantial difference in his snippets. – BlackBear Feb 19 '11 at 18:31
  • I only mean to point out that not only is there no **substantial** difference in your examples, there's actually no difference **at all**. Two instructions in a tight loop can be an enormous difference, FWIW, but one wouldn't worry about that here because it is easily optimized away by the compiler. – Stephen Canon Feb 19 '11 at 18:33
  • @Stephen Canon: Yep. Actually my gcc with -o3 doesn't replace the loops with add/sub – BlackBear Feb 19 '11 at 18:35
  • really? that's perverse. With `gcc-4.2 -Os -arch i386` I get `addl $11, 4(%eax)`. Ditto for `clang` and `icc`. – Stephen Canon Feb 19 '11 at 18:37
0

Well, with the first version you only have to release once, after the loop. With the second version you can't use the pointer from outside the loop, so you need to release inside the loop. Memory-wise it shouldn't matter that much, but you do have allocation overhead in your second example I think.

Kevin Renskers
  • 5,156
  • 4
  • 47
  • 95
  • 2
    Whether or not there is allocation overhead in either case, and whether or not you need to release within the loop, depends entirely on what the expression `something` is. – Stephen Canon Feb 19 '11 at 18:32
0

check out a similar answer on stackoverflow here with some good answers. However this is probably compiler/language independent...

Community
  • 1
  • 1
akobre01
  • 777
  • 1
  • 10
  • 22