###質問内容
swiftで英単語(engメンバ)と日本語訳(jpnメンバ)と次のノードへのポインタnextを持つ構造体によって、リスト構造を作りました。
そして、関数addListを使って、allocで新たなノードポインタを動的メモリ確保し、その後engメンバとjpnメンバに単語を代入するプログラムを作りました。
しかし、関数addList内で動的メモリ確保には成功している(nilは入っていない)ものの、engメンバやjpnメンバに文字を代入しようとすると、EXC_BAD_ACCESSとでて、できません。
ただし、これは、addList内でノードポインタを動的メモリ確保したとき、メモリサイズが小さいときに起こるようなのです。実機(iphone5s)で試してみたところ、sizeof(WordStruct)*160付近がEXC_BAD_ACCESSが出るか出ないかの境界のようで、sizeof(WordStuct)*256などとすると安定して動作します。
このことから、動的メモリ確保(alloc)が原因かとも思うのですが、調べても全くわかりません。どなたか詳しい方、お助けください。
###該当のソースコード
import UIKit import Foundation extension Character { func unicodeScalarCodePoint() -> UInt32 { let characterString = String(self) let scalars = characterString.unicodeScalars return scalars[scalars.startIndex].value } } struct WordStruct{ var eng : String var jpn : String var next : UnsafeMutablePointer<WordStruct> = nil } class ViewController: UIViewController { func getHashNum(str:String)->Int{ if(str.characters.count==0){ return 26 } else{ let firstStr = str[str.startIndex] let hash = firstStr.unicodeScalarCodePoint()-97 return Int(hash) } } func addList(strEng:String,strJpn:String,list:Array<UnsafeMutablePointer<WordStruct>>)->UnsafeMutablePointer<WordStruct>{ print("addList start") let hash = getHashNum(strEng) var newList = list[hash] let add = UnsafeMutablePointer<WordStruct>.alloc(sizeof(WordStruct)*165) if(add == nil){ print("error: add == nil!") } else{ print("succeed: add != nil!") } add.memory.eng = strEng //ここでエラー! add.memory.jpn = strJpn add.memory.next = newList newList = add print("addList end") return newList } override func viewDidLoad() { super.viewDidLoad() let tango = ["apple","ringo","bear","kuma"] var list = Array<UnsafeMutablePointer<WordStruct>>(count:26,repeatedValue:nil) print("number of tango = \(tango.count)") for r in 0..<tango.count/2{ let hash = getHashNum(tango[2*r]) list[hash] = addList(tango[2*r],strJpn:tango[2*r+1],list: list) } for m in 0..<26{ while(list[m] != nil){ print(list[m].memory.eng,list[m].memory.jpn) list[m] = list[m].memory.next } } print("succeed!") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
###実行結果
number of tango = 4 addList start succeed: add != nil! (lldb)
###エラーメッセージ
Thread1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
###追記
UnsafeMutablePointerを使うほうが高速だと思っていました。ポインタを使った理由はとりあえずコードが思いついたからです。
回答1件
あなたの回答
tips
プレビュー