Vik Singh
Vik Singh

Reputation: 1603

Generic Swift struct: Segmentation fault: 11

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

Answers (2)

MathewS
MathewS

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

OOPer
OOPer

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

Related Questions