Bad_Access During Recursive Calls in Swift

BAD_ACCESS during recursive calls in Swift

The runtime error that you are experiencing here is a stack overflow. The fact that you do not experience it when modifying the definition to use a struct does not mean it will not occur. Increase the iteration depth just slightly and you will also be able to achieve the same runtime error with the struct implementation. It will get to this point sooner with the class implementation because of the implicit arguments being passed around.

Is my recursive function failing due to a stack overflow? If yes, given my function definition, is it normal?

This is likely a stack overflow, function hasView is called cursively with a depth roughly equal to count and the stack has to store count adresses which could exceed the stack size for huge numbers.

More details in another post: BAD_ACCESS during recursive calls in Swift

Please note that what you implemented seems to be a running maximum in reverse order returning the indices and this can implemented more efficiently without overflow like this:

func runningMax(_ arr: [Int]) -> [Int] {
var max = 0
var out = [Int]()

for (i, element) in arr.enumerated().reversed() {
if element > max {
max = element
out.append(i)
}
}

return out.reversed()
}

I compared this with your algorithm and the outputs seems to be identical. I also tested with larges values up to 100,000,000 and it is fine.

Returned array does not need to be optional, if the input array is empty so do the output array.

EXC_BAD_ACCESS code=2 in recursive method with ARC

It's clear from the stack trace that your recursion is too deep for the stack. Even though there is a lot of RAM available the stack is limited. The maximum stack size is a little unclear but I think it may be no more than 1MB.

Swift: EXC_BAD_ACCESS calling a method from a generic type that implements a protocol

It is a compiler bug, resulting in a stack overflow when accessing the localObjects property. From what I can gather, it is an issue with a recursive dependency between your types, and more specifically that localObjects is invoked via dynamic dispatch. If I remove the static var localObjects: ResourceFinderType { get } from Resource it works.

Alternatively, if you remove the Resource constraint from ResourceFinder, it will also run successfully.

I have reported the issue and you can track it via SR-1314

swift setter causing exc_bad_access

@vadian has provided a solution in his answer, which should fix your problem. Let me just explain what's happening.

You have created a computed property, i.e. a property which is not backed by a variable, instead both the getter and the setter do some processing, usually on another stored property, in order to respectively return a value and set a new value.

This is your computed property:

var test: NSNumber {
get { return self.test }
set {
println(newValue)
self.test = newValue
}
}

Look at the getter implementation:

return self.test

What does it do? It reads the test property of the current instance, and returns it. Which is the test property? It's this one:

var test: NSNumber {
get { return self.test }
set {
println(newValue)
self.test = newValue
}
}

Yes, it's the same property. What your getter does is to recursively and indefinitely calling itself, until a crash happen at runtime.

The same rule applies to the setter:

self.test = newValue 

it keeps invoking itself, until the app crashes.

How can I perform recursive methods with generic class

Your multiplication algorithm is only valid if b is a non-negative integer. If b is negative, or includes a fraction, then b == 0 will never become true. If you at least constrain type T to UnsignedInteger, then the compiler enforces those limitations at compile-time:

class Math5<T: UnsignedInteger> {

You can generalize so that the first argument can be any AdditiveArithmetic while only allowing an UnsignedInteger for the second argument. Let's drop the class and use a free function:

func multiply<LHS: AdditiveArithmetic, RHS: UnsignedInteger>(
_ lhs: LHS,
_ rhs: RHS
) -> LHS {
guard lhs != .zero && rhs != 0 else { return .zero }
return lhs + multiply(lhs, rhs - 1)
}

multiply(2.5, 3 as UInt) // result: 7.5

You can still crash with a stack overflow if you pass in a large enough value for b. Since Swift doesn't guarantee tail call elimination, you should also change your algorithm to use a loop instead of recursion if you want to avoid stack overflows.

func multiply<LHS: AdditiveArithmetic, RHS: UnsignedInteger>(
_ lhs: LHS,
_ rhs: RHS
) -> LHS {
guard lhs != .zero else { return .zero }
var answer: LHS = .zero
var rhs = rhs
while rhs > 0 {
answer += lhs
rhs -= 1
}
return answer
}

Why is this recursive routine giving EXC_BAD_ACCESS (code=1, address=0x8)?

There seems to be something wrong with passing the array "toRead" of
NodeData* recursively

That is not correct.

It failed when (and because) current was zero.

If you believed something about your design made current reliably not zero at that point, you need to fix that design error. Because we can see it IS zero.

If other parts of the design were not supposed to guarantee current points to a valid object at this point, then the code you showed should be testing it before using it.

Swift recursive closure stack overflow bug

You're causing a stack overflow, by having getLocation(completion:) call getLocation(completion:), which calls getLocation(completion:), ... until you run out of stack space.

You could use a DispatchSourceTimer instead:

import Dispatch

let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
timer.schedule(deadline: .now(), repeating: .seconds(5), leeway: .milliseconds(100))

timer.setEventHandler { [weak self] in
guard let strongSelf = self,
let location = LocationManager.shared.currentLocation else { return }
strongSelf.lonLabel.text = "Lat: \(location.latitude)"
strongSelf.latLabel.text = "Lon: \(location.longitude)"
}

timer.resume()

But this whole polling approach just doesn't make any sense. Your location delegate is already being informed of location changes. You can just change your labels then.

Swift: Repeatedly calling a closure passed through identity function causes EXC_BAD_ACCESS code=2

This is a bug in Swift. Track the issue here, https://bugs.swift.org/browse/SR-7179.



Related Topics



Leave a reply



Submit