Crash when compare 2 String many of times

I have a array of contacts (about 1 millions elements), i must compare many of times the id of a contact to find out contact i need (the list was order by id so i'm using binary search). It did crash, this is my code and backtrace:

struct Contact {
  let blIdContact: String
  let timeStamp: Int64
}
func binarySearch(in contacts: [Contact], for value: String) -> Int? {
  var left = 0
  var right = contacts.count - 1
  while left <= right {
    let middle = Int(floor(Double(left + right) / 2.0))
    if contacts[middle].blIdContact < value {
      left = middle + 1
    } else if contacts[middle].blIdContact > value {
      right = middle - 1
    } else {
      return middle
    }
  }
  return nil
}

This is backtrace at crashed thread:

Thread 25 Crashed:
0   libobjc.A.dylib               	0x00000001b38771c8 objc_msgSend + 8
1   libswiftCore.dylib            	0x00000001a2b1a464 _foreignNormalize(readIndex:endIndex:guts:outputBuffer:icuInputBuffer:icuOutputBuffer:) + 236 (StringBridge.swift:159)
2   libswiftCore.dylib            	0x00000001a2b231cc _StringGutsSlice._slowCompare(with:expecting:) + 3464 (StringComparison.swift:375)
3   libswiftCore.dylib            	0x00000001a2b2115c _stringCompareInternal(_:_:expecting:) + 308 (StringComparison.swift:185)
4   Bluezone                      	0x00000001023f1450 binarySearch(in:for:) + 37968 (Utils.swift:46)

This is full backtrace:

Answered by DTS Engineer in 688191022

Crash when compare 2 String many of times

See my response on your other thread.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

When does it crash (could you print left and right at each step ?

Are you sure contacts are fully ordered by id ? Are blIdContact all strings from Int ?

There is something I don't understand in your code:

  • how could left be greater than right ?
  • Are you sure your id are such that < comparison works in this case ("300" is not less than "1000" because of string comparison).

Have one thing i didn't mention above, in thread 25 note about index of line crashed (Utils.swift:46) it's:

if contacts[middle].blIdContact < value {
Accepted Answer

Crash when compare 2 String many of times

See my response on your other thread.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I do not see the index error in crash log:

Thread 25 Crashed:
0   libobjc.A.dylib               	0x00000001b38771c8 objc_msgSend + 8
1   libswiftCore.dylib            	0x00000001a2b1a464 _foreignNormalize(readIndex:endIndex:guts:outputBuffer:icuInputBuffer:icuOutputBuffer:) + 236 (StringBridge.swift:159)
2   libswiftCore.dylib            	0x00000001a2b231cc _StringGutsSlice._slowCompare(with:expecting:) + 3464 (StringComparison.swift:375)
3   libswiftCore.dylib            	0x00000001a2b2115c _stringCompareInternal(_:_:expecting:) + 308 (StringComparison.swift:185)
4   Bluezone                      	0x00000001023f1450 binarySearch(in:for:) + 37968 (Utils.swift:46)
5   Bluezone                      	0x00000001024028c4 specialized static BluezoneIdTrace.checkContactF(bluezoneDailyKeyk:timeDk:max:timeTe:) + 108740 (BluezoneIdTrace.swift:307)
6   Bluezone                      	0x0000000102401928 static BluezoneIdTrace.isContactF(dataF0:) + 104744 (BluezoneIdTrace.swift:255)
7   Bluezone                      	0x0000000102412158 partial apply for closure #1 in ScannerManager.checkContactF(_:resolve:rejecter:) + 172376 (<compiler-generated>:0)
8   Bluezone                      	0x000000010240d6f4 thunk for @escaping @callee_guaranteed () -> () + 153332 (<compiler-generated>:0)
9   libdispatch.dylib             	0x000000019e9c1a84 _dispatch_call_block_and_release + 32 (init.c:1466)
10  libdispatch.dylib             	0x000000019e9c381c _dispatch_client_callout + 20 (object.m:559)
11  libdispatch.dylib             	0x000000019e9cb004 _dispatch_lane_serial_drain + 620 (inline_internal.h:2557)
12  libdispatch.dylib             	0x000000019e9cbc00 _dispatch_lane_invoke + 404 (queue.c:3862)
13  libdispatch.dylib             	0x000000019e9d64bc _dispatch_workloop_worker_thread + 764 (queue.c:6589)
14  libsystem_pthread.dylib       	0x00000001ea93a7a4 _pthread_wqthread + 276
15  libsystem_pthread.dylib       	0x00000001ea94174c start_wqthread + 8

How do you load the 1M+ contacts ? Are you sure it is fully loaded when you call binarySearch ?

So, add some print statements:

    let middle = Int(floor(Double(left + right) / 2.0))
    print("middle", middle)
    print("contact", contacts[middle])
    print("contact Id",  contacts[middle].blIdContact)
    print("value", value)
    if contacts[middle].blIdContact < value {

What do you get just before crash ?

I tried your code a few tens of times with 100 millions elements in contacts. It never crashed. So the number of String comparison does not matter. I guess it is a problem of multithreading, as it may be revealed only when huge number of elements involved. Anyway, you should better concentrate on the first thread of yours and respond to eskimo.

Crash when compare 2 String many of times
 
 
Q