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
"This Class Is Not Key Value Coding-Compliant" Using Coreimage
Variable with Getter/Setter Cannot Have Initial Value, on Overridden Stored Property
How to Access The Firebase Topics a User Is Subscribed To
Difference Between Sort and Sortinplace in Swift 2
Cocoa: Simulating Command+Tab in Cgevent
Why This Line Is Not Covered? Xcode Code Coverage
Why Do I Get Source Kit Service Terminated Error
How to Use The Snapchat Sdk (Snapkit) with Swiftui
How to Distinguish Bool and Int in Swift
How to Observe Object's Property in Rxswift
What Was The Reason for Swift Assignment Evaluation to Void
Fbsdksharephoto Not Sharing Link Alongside Photo Using Swift
How to Handle Error with Realm During Writing
Destructuring Tuple of Tuple in Closure
Reachability Change Notification Should Be Called Only Once
How to Set First Responder for Nstextview in Swift