While toying with Swift, I've encountered a situation which crashes and I still not have figured out why.
Let define:
class TestClass {
var iteration: Int = 0
func tick() -> Void{
if iteration > 100000 {
print("Done!")
return
}
iteration++
tick()
}
}
The tick()
function calls itself and each time increments iteration
. Any call of the type
let test = TestClass()
test.tick()
makes the program crash after a rather small number of recursions (around 50000 on my iMac), with a EXC_BAD_ACCESS
error:
If I define a similar struct
instead of a class
, there is no crash (at least not in these limits). Note that when it crashes, the program uses only a few MB of RAM.
I can't explain yet why this crashes. Does anybody have an explanation? The callbackStorage
value seem suspicious but I haven't found any pointer on this.
In your program, each thread has something called a stack. A stack is a LIFO (last in first out) - a data container that has 2 main operations: push, which adds an element to the top of the stack, and pop, which removes an item from the top of the stack.
When your program calls a function, it pushes the location of the code that called the function, called the return address, (and sometimes some of the function's arguments also), then jumps to that function's code. (The function's local variables are also stored on the stack.) When the function returns, it pops the return address off of the stack and jumps to it.
However, the stack has a limited size. In your example, your function calls itself so many times that there isn't enough room in the stack for all of the return addresses, arguments, and local variables. This is called a stack overflow (which is where this website got its name from). The program tries to write past the end of the stack, causing a segfault.
The reason why the program doesn't crash when you use a struct
is likely, as dans3itz said, because classes have more overhead than structs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With