0

I've had trouble before with this same program because it makes lots of memory allocations. I got rid of most problems but I'm still having trouble with one particular problem. When I ran my program in Eclipse it compiles well but it crashes with this message

*** glibc detected *** /home/user/workspace/TTPrueba/Debug/TTPrueba: free(): invalid pointer: 0xb6bc0588 ***

When I ran it with Valgrind it tells me this

==31580== Process terminating with default action of signal 11 (SIGSEGV)
==31580==  Access not within mapped region at address 0x0
==31580==    at 0x804BEA3: termino (Menu.c:899)
==31580==    by 0x804BE05: computar_transformadas (Menu.c:840)

So the problem is that it is trying to free an invalid memory address but then I go step by step in debug mode and the program never crashes!!!! :(

Any idea why such a thing could happen? How come it works while debugging but not while running? This is pretty strange behavior.

for(phi=0;phi<360;phi++){

      for(j=0;j<par.param1[phi][0];j++){


              for(o=0;o<(par.prueba[phi][j][1]-par.prueba[phi][j][0]);o++){//AQUI 849

                 free(par.pixels[phi][j][o]);//HERE IS LINE 899 WHERE IT ALWAYS CRASHES

                 if(o==(par.prueba[phi][j][1]-par.prueba[phi][j][0]-1))
                     free(par.pixels[phi][j]);

              }


          free(par.prueba[phi][j]);

      }

Thanks for the help!

Atirag
  • 1,660
  • 7
  • 32
  • 60
  • 5
    Ah. The lovely--and not *nearly* rare enough--[Heisenbug](http://en.wikipedia.org/wiki/Heisenbug) in it's natural habitat. See the beautiful camouflage pattern of the plumage? What's that? You can't see it? Well, yes. That's how you know it's there. – dmckee --- ex-moderator kitten Apr 11 '12 at 23:47
  • 2
    In the debugger the memory maybe zero, in your program this may not be the case. Try to change your mallocs to callocs. – Mikhail Apr 11 '12 at 23:48
  • 2
    "I go step by step in debug mode and the program never crashes!!!! " - welcome to the world of debugging! – Mitch Wheat Apr 11 '12 at 23:49
  • You don't show your malloc code... – Mitch Wheat Apr 11 '12 at 23:50
  • Lol @ the hisenbug but ok it gave me tips. Valgrind also warns me of unitialized values but I ignored them because I thought that if the debugger was fine then that wasn't a problem but apparently it is! Will it work if I initialize everything to 0 first? – Atirag Apr 11 '12 at 23:58
  • Valgrind looks to be telling you exactly where the problem is -- Menu.c line 899 -- where one of the pointers involved is 0 – Chris Dodd Apr 12 '12 at 00:05
  • 1
    Why the if(o==...) free() in the third for loop? – Morpfh Apr 12 '12 at 00:06
  • @user120115 because I can only free par.pixels[phi][j] after freeing all par.pixels[phi][j][o] – Atirag Apr 12 '12 at 00:20
  • Ok, I replaced all my mallocs with callocs to make sure the values are initialized and valgrind no longer complains of uninitialized values but it crashes the same in the same place :( – Atirag Apr 12 '12 at 00:21
  • @ChrisDodd if the pointer is 0 that means it will crash? So using calloc is useless in this case? – Atirag Apr 12 '12 at 00:25
  • @Atirag: Why not put it after the for loop? Makes the code much harder to read - and adds redundant check. (Unless there is something I'm not seeing here.) – Morpfh Apr 12 '12 at 00:32
  • @user120115 Yeah the loop is also implicitly checking that the par.pixels[phi][j] was initialized. If I put it after the loop there's no check so it gives an error – Atirag Apr 12 '12 at 00:35
  • @Atirag: Ah. OK. Sorry for waisting your time ;) – Morpfh Apr 12 '12 at 00:42
  • @user120115 No don't worry! thnx for trying to help! :) – Atirag Apr 12 '12 at 00:45

3 Answers3

0

One likely reason -- the debugger could be changing the memory layout of things, so when memory is corrupted, it happens to be in an "out of the way" place.

Or the debugger might be causing allocated memory to be zeroed which may not be happening in a production run.

QuantumMechanic
  • 13,795
  • 4
  • 45
  • 66
  • 1
    or the implicit synchronisation of using the debugger to stop at breakpoints is changing the timing interaction of threads... (if multithreaded) – Mitch Wheat Apr 11 '12 at 23:51
  • Not multithreaded so that's not the problem. I think some unitialized values are the problem. – Atirag Apr 11 '12 at 23:58
0

It is not surprising. For example if par.pixels[phi][j][o] is not initialized. It can contain anything, in a debugger environment, you have different memory layout par.pixels[phi][j][o] may become 0, so free didn't crash.

pizza
  • 7,296
  • 1
  • 25
  • 22
  • Besides using calloc (ensuring the pointers are initially set to NULL, making any attempt to erroneously dereference them obvious), it's a good practice to set pointers to NULL after freeing the memory they point to (for the same reason). Or sometimes when debugging, a "poison" value (say, 0xdeadbeefdeadbeef) that will stand out in error messages / debug prints. – Scott Lamb Apr 12 '12 at 06:49
  • How can I do that? for example if I do free(par.pixels[phi][j][o]); should I do something afterwards? – Atirag Apr 12 '12 at 20:18
  • you can't fix it if you never initialized it. Check where it came from, it had to be assigned a result from malloc() for it to be a valid free() candidate. – pizza Apr 12 '12 at 20:48
  • Question: If par.pixels[phi][j][o] is a signed int and the value that it holds is bigger than 32767 that will cause a problem while freeing the memory right? – Atirag Apr 13 '12 at 00:08
  • par.pixels[phi][j][o] should not be a signed int, it should be a pointer type, it is suppose to contain the return value of a previous malloc() call. The value is not important. – pizza Apr 13 '12 at 00:10
  • But this is how I do the malloc par.pixels[phi][j][o] = (int *)calloc( 2, sizeof ( int ) ); and according to this http://stackoverflow.com/questions/1119134/how-do-malloc-and-free-work it might cause a problem if the value it holds is bigger than the defined type since it could overwrite other memory locations. – Atirag Apr 13 '12 at 15:09
  • if the type of par.pixels[phi][j][o] is a pointer, it will be the same as the return type of malloc, and since you cast (int *), that has to be the case, the post you mentioned is not related to your problem and I think you misunderstood it. The most likely cause of your problem, I am guessing here, is that you never actually written into that location and then you go and free it. – pizza Apr 13 '12 at 21:07
  • Ok somehow the thing fixed it, I think it was a combination of things that were wrong. Thanks a lot for the help! :) – Atirag Apr 14 '12 at 15:56
0

One problem that I see is that you free par.pixels[phi][j][o] where o looping from zero, and then access par.pixels[phi][j][0], which just have been free'd!

You also free par.pixels[phi][j] but continue looping accessing par.pixels[phi][j] and freeing pointers that a no longer valid.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I never access par.pixels[phi][j][0] after freeing par.pixels[phi][j][o] I access par.prueba[phi][j][0]. – Atirag Apr 12 '12 at 20:14
  • Also when I free par.pixels[phi][j] I make sure it is the last loop so the next it will come out of it and stop freeing memory – Atirag Apr 12 '12 at 20:15