Re: Segmentation Fault



Rahul <nospam@xxxxxxxxxx> wrote:
I believe my code is correct and caches all results in an Array for
efficiency (only look up is needed). But it generates a Segmentation Fault
everytime I run it.

First of all, you need to compile with max warnings set.

c99 -o foo foo.c

foo.c:8: warning: return type defaults to â??intâ??
* foo.c: In function â??setupsquaresâ??:
* foo.c:10: warning: operation on â??iâ?? may be undefined
foo.c: At top level:
foo.c:20: warning: return type defaults to â??intâ??
foo.c:25: warning: return type defaults to â??intâ??
foo.c: In function â??printsquareâ??:
foo.c:22: warning: control reaches end of non-void function
foo.c: In function â??setupsquaresâ??:
foo.c:11: warning: control reaches end of non-void function

The one I've marked is particularly nasty. See this link for more info:
http://c-faq.com/expr/evalorder1.html

You can replace that for-loop with this:

for(i = 0; i < INT_MAX; squares[i * i] = true, i++);

although it would be more idiomatic and clearer to write:

for(i = 0; i < INT_MAX; i++) {
squares[i * i] = true;
}

With this fix, it still dumps core (but it takes a little longer to do
it. :) )

Now I'm going to take you on a little detour, assuming you're on a
Unix-type machine--note the -g on the gcc command line to embed symbolic
debugging info:

$ ulimit -c unlimited # unlimit core dump file size
$ gcc -Wall -Wextra -std=c99 -pedantic -g -o foo foo.c
$ ./foo
Segmentation fault (core dumped)
$ gdb -tui foo -c core

gdb instantly shows me that it crashed on line 10 (the for loop). So I
use "p" to print some values:

(gdb) p i
$1 = 46341
(gdb) p squares[i*i]
Cannot access memory at address 0xffffffff80601bf9
(gdb) p i*i
$2 = -2147479015

Whoa--that's not a good index.

So you're trying to run i all the way up to INT_MAX, square it, and use
that as an index into an array of INT_MAX elements. But because you're
squaring it, as soon as i becomes greater than the sqrt(INT_MAX), you're
going to overflow the int; IOW:

(sqrt(INT_MAX)+1)^2 > INT_MAX;

So what you want is to go up to the square root of the size of your
array.

However, that /still/ doesn't fix it for me, because INT_MAX is so high,
having that huge array is causing problems when I try to populate it. I
don't have enough memory.

Instead, just have the for-loop populate the array up through the first,
say, 100 squares (which means the square array needs to have 100*100
elements). You're only testing the first 10 of those numbers anyway:

$ ./foo
0 true
1 true
2 false
3 false
4 true
5 false
6 false
7 false
8 false
9 true
10 false

Whew!

Now we can argue if this is a good approach, or if just using sqrt()
would be faster. I just wrote a naive program that tested all numbers
between 0 and 1 billion for perfect squares; runtime: 16 seconds,
perfect squares found: 31623. My computer should be able to do
something like 25 million square roots per second...

(I wrote another program to generate perfect squares and compared the
output of the two for verification.)

-Beej

.



Relevant Pages

  • Re: Data compression in roguelikes
    ... Gerry Quinn wrote: ... think Breshenham circle drawing algorithm is simple too). ... scan the enclosing square. ... whatever language that is that you don't go outside the map array, ...
    (rec.games.roguelike.development)
  • Re: Chess boards & connections.
    ... and 16 for White to start, and since each pawn ... How many choices for a square do ... All I needed was the 2D Array ... complications when calculating possable moves. ...
    (sci.math)
  • Re: Chess boards & connections.
    ... How many choices for a square do ... All I needed was the 2D Array ... Well then provide the needed Array, ... if your math skills indicate your programming skills, ...
    (sci.math)
  • Re: Chess boards & connections.
    ... How many choices for a square do ... All I needed was the 2D Array ... Well then provide the needed Array, ... if your math skills indicate your programming skills, ...
    (sci.math)
  • Re: M31 from the deep south
    ... around the left of the "great square", and finally found a smudge of light. ... M31! ... This was the core of the core I assume. ...
    (sci.astro.amateur)