Reputation: 1603
I am trying to implement a struct with generic type that conforms to Hashable protocol. Can anybody help me understand why am I getting "Segmentation fault: 11" error with the following code.
I would really appreciate any insights regarding this.
struct Pmf<Element: Hashable> {
typealias Distribution = [Element : Float]
fileprivate var normalized = false
fileprivate var distribution:[Element : Float] = [ : ] {
didSet {
self.normalized = false
}
}
}
extension Pmf {
init(values: [Element], withProbs probs: [Float]) {
for pair in zip(values, probs) {
self.distribution[pair.0] = pair.1
}
}
var probDist: Distribution {
mutating get {
if !normalized {
self.normalize()
}
return self.distribution
}
}
subscript(value: Element) -> Float? {
mutating get {
if !normalized {
self.normalize()
}
return self.distribution[value]
}
set(prob) {
self.distribution[value] = prob
}
}
mutating func normalize() {
for (key, val) in self.distribution {
self.distribution[key] = val / Float(self.distribution.count)
}
}
}
var pp = Pmf<String>()
pp["One"] = 4
pp["Two"] = 5
pp["three"] = 5
print(pp)
Upvotes: 1
Views: 402
Reputation: 2307
I starting writing a bug report for the similar situation (adding method deceleration using a generic with an associated type) and was getting segmentation faults every possible combination I tried.
I started to write a 'Minimum Verifiable Example' in a playground and found I couldn't replicate the fault.
The only difference between app and playground was that app had protocol and method in different source files.
I combined the two source files and no more segmentation fault!!
This took hours of my time to track down, hope it helps someone else.
Update: Submitted a bug for this fault, if you're encountering this too, please add a comment to let the team know you've encountered it: https://bugs.swift.org/browse/SR-3595
Upvotes: 1
Reputation: 47886
Seems you need a little trick to define an initializer for a value type in an extension:
Add one line to your init(values:withProbs:)
as shown below:
init(values: [Element], withProbs probs: [Float]) {
self.init() //<-
for pair in zip(values, probs) {
self.distribution[pair.0] = pair.1
}
}
Anyway compilers should not crash with SegFault 11. Even if the source code has some fault in it.
You'd better send a Bug Report to Apple, or to swift.org.
Upvotes: 1