質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

1回答

2036閲覧

【swiftでリスト構造】String型メンバに代入するとEXC_BAD_ACCESSが出る

tetsutail

総合スコア81

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/07/02 03:47

編集2016/07/02 09:38

###質問内容
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を使うほうが高速だと思っていました。ポインタを使った理由はとりあえずコードが思いついたからです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u39ueda

2016/07/02 09:16

UnsafeMutablePointerを使うのは必要ですか?使わないほうが簡単かつ安全に(そしておそらく高速なコードが)書けると思うのですが…
tetsutail

2016/07/02 09:39

使わない場合、単にポインタではなくそのまま構造体を使えばよいということでしょうか?
tetsutail

2016/07/02 12:11

2次元配列にすればできました。回答ありがとうございました。
fuzzball

2016/07/04 00:18 編集

解決しているなら閉めて下さい。質問のコードで落ちる原因を知りたいのであれば、その旨追記して下さい。
guest

回答1

0

自己解決

自己解決したので受付終了します。
ご迷惑おかけしてすみません。

投稿2016/07/04 02:51

tetsutail

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問