1

注: 的問題是誤導。我認爲有人使用會導致內存錯誤多個參數..但是這不是原因..原因是一個錯誤地形成的SQL語句..請參閱下面的the answerIOS:使用不止一次同sqlite的參數會導致過早的內存釋放

如果創建使用相同的參數更多的sqlite的聲明不止一次即

NSString* updateStmt = @"INSERT INTO search_email(..., subject, ...)" 
    " SELECT ..., :subject, ...," 
    " coalesce((SELECT search_email.threadID " 
    " FROM search_email " 
    " WHERE search_email.subject MATCH :subject2 " 
    ")," 
    " :uid" 
    ")"; 

int subjectIndex = sqlite3_bind_parameter_index(searchEmailInsertStmt,":subject"); 
int subjectIndex2 = sqlite3_bind_parameter_index(searchEmailInsertStmt,":subject2"); 

...  
sqlite3_bind_text(searchEmailInsertStmt, subjectIndex, [subject UTF8String], -1, SQLITE_TRANSIENT);  // subject 
sqlite3_bind_text(searchEmailInsertStmt, subjectIndex2, [subjectCopy UTF8String], -1, SQLITE_TRANSIENT);  // search_email.subject 


if (sqlite3_step(searchEmailInsertStmt) != SQLITE_DONE) { 
    NSLog(@"Failed step in searchEmailInsertStmt: '%s', '%i'", sqlite3_errmsg([[AddEmailDBAccessor sharedManager] database]), pk); 
} 

那麼它崩潰,出現以下錯誤: malloc: *** error for object 0x9b6350: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

任何想法,爲什麼?

更新: 如果我更換主題和subjectCopy與字符串常量,即@「subject1」和@「subject2」它工作得很好..但由於某種原因,我試圖複製這種編程方式即

NSString* subjectCopy = [NSString alloc]; 
subjectCopy = [subject retain]; 

並且這些工作都沒有工作..也將SQLITE_TRANSIENT更改爲SQLITE_STATIC不起作用。

更新2:輸出的BT在malloc_error_break突破後:

thread #6: tid = 0x2503, 0x99a20815 libsystem_c.dylib`malloc_error_break, stop reason = breakpoint 1.1 
frame #0: 0x99a20815 libsystem_c.dylib`malloc_error_break 
frame #1: 0x99a21d51 libsystem_c.dylib`free + 346 
frame #2: 0x0005d5e8 reMail`sqlite3MemFree + 40 at sqlite3.c:12272 
frame #3: 0x0002a53e reMail`sqlite3_free + 126 at sqlite3.c:15653 
frame #4: 0x0004e670 reMail`sqlite3Fts3ExprFree + 64 at sqlite3.c:101490 
frame #5: 0x0004e665 reMail`sqlite3Fts3ExprFree + 53 at sqlite3.c:101489 
frame #6: 0x0003fbf1 reMail`fulltextClose + 49 at sqlite3.c:97401 
frame #7: 0x000b48f3 reMail`sqlite3VdbeFreeCursor + 163 at sqlite3.c:47461 
frame #8: 0x000aebb8 reMail`sqlite3VdbeExec + 17576 at sqlite3.c:54042 
frame #9: 0x00032273 reMail`sqlite3Step + 467 at sqlite3.c:49459 
frame #10: 0x00031f5e reMail`sqlite3_step + 78 at sqlite3.c:49531 
frame #11: 0x000ff2ae reMail`-[EmailProcessor insertIntoSearch:withMetaString:withUid:withSubject:withBody:withFrom:withTo:withCc:withFolder:] + 1854 at EmailProcessor.m:934 
frame #12: 0x001005a1 reMail`-[EmailProcessor addEmail:] + 3153 at EmailProcessor.m:1015 
frame #13: 0x000fd673 reMail`-[EmailProcessor addEmailWrapper:] + 4035 at EmailProcessor.m:651 
frame #14: 0x0324c1bd CoreFoundation`__invoking___ + 29 
frame #15: 0x0324c0d6 CoreFoundation`-[NSInvocation invoke] + 342 
frame #16: 0x017c36b5 Foundation`-[NSInvocationOperation main] + 45 
frame #17: 0x01738d23 Foundation`-[__NSOperationInternal start] + 736 
frame #18: 0x01738a34 Foundation`-[NSOperation start] + 79 
frame #19: 0x017c5301 Foundation`__block_global_6 + 150 
frame #20: 0x02ec053f libdispatch.dylib`_dispatch_call_block_and_release + 15 
frame #21: 0x02ed2014 libdispatch.dylib`_dispatch_client_callout + 14 
frame #22: 0x02ec32e8 libdispatch.dylib`_dispatch_root_queue_drain + 335 
frame #23: 0x02ec3450 libdispatch.dylib`_dispatch_worker_thread2 + 39 
frame #24: 0x99a09e12 libsystem_c.dylib`_pthread_wqthread + 441 
+0

爲什麼你使用'SQLITE_TRANSIENT'? – trojanfoe

+0

':1,$ s/SQLITE_TRANSIENT/0/g'我願意這樣做。 – trojanfoe

+0

我不知道大聲笑..該代碼是從[remail](http://code.google.com/p/remail-iphone/)電子郵件客戶端的人複製的..但我很好奇實現你的建議..最後的東西看起來像這樣'sqlite3_bind_text(searchEmailInsertStmt,8,[文件夾UTF8String],-1,:1,$ s/SQLITE_TRANSIENT/0/g);'? – abbood

回答

0

我終於找到了!在追逐了這麼多的紅鯡魚之後,我得到的最好的建議是on a forum specialized for sqlite:關鍵在於保持sqlite的調試範圍,但它不太可能是sqlite的錯。

我基本上決定打破我的sql語句成小塊,並在它自己的運行的每個:

原來的SQL導致記憶問題陳述:

NSString* updateStmt = @"INSERT INTO search_email(docid, meta, subject, body, sender, tos, ccs, folder, threadid)" 
    " SELECT ?, ?, ?, ?, ?, ?, ?, ?," 
    " coalesce((SELECT search_email.threadID " 
    " FROM search_email " 
    " WHERE search_email.subject MATCH ? UNION SELECT * FROM " 
    " (SELECT threadID FROM (SELECT threadID FROM search_email WHERE search_email.sender MATCH ? " 
    " INTERSECT SELECT threadID FROM search_email WHERE search_email.tos MATCH ?) " 
    " UNION " 
    " SELECT threadID FROM (SELECT threadID FROM search_email WHERE search_email.sender MATCH ? " 
    "  INTERSECT SELECT threadID FROM search_email WHERE search_email.tos MATCH ?)) " 
    " LIMIT 1" 
    ")," 
    " ?" 
    ")"; 

發生問題,只要我提供具有特殊字符的字符串以匹配.. 以下是發送給MATCH的有問題參數的示例:

sabaho :)
2月1日的新核心音頻問題 - Stack Exchange
Ref;以芝加哥,伊利諾伊州的數據爲中心的測試/ ETL測試機構。

所以首先使用正則表達式來繞去,我簡單地更換與之匹配的正常=比較..但清理參數:

NSError *error = NULL; 
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"re:(\\s)*" 
                     options:NSRegularExpressionCaseInsensitive 
                     error:&error]; 


          error:&error]; 

NSString *filteredSubjectFromRe = [regex stringByReplacingMatchesInString:subject 
                    options:0 
                    range:NSMakeRange(0, [subject length]) 
                  withTemplate:@""]; 

if(searchEmailInsertStmt == nil) { 

    NSString* updateStmt = @"INSERT INTO search_email(docid, meta, subject, body, sender, tos, ccs, folder, threadid)" 
    " SELECT ?, ?, ?, ?, ?, ?, ?, ?," 
    " coalesce((SELECT search_email.threadID " 
    " FROM search_email " 
    " WHERE search_email.subject = ? UNION SELECT * FROM " 
    " (SELECT threadID FROM (SELECT threadID FROM search_email WHERE search_email.sender = ? " 
    " INTERSECT SELECT threadID FROM search_email WHERE search_email.tos = ?) " 
    " UNION " 
    " SELECT threadID FROM (SELECT threadID FROM search_email WHERE search_email.sender = ? " 
    "  INTERSECT SELECT threadID FROM search_email WHERE search_email.tos = ?)) " 
    " LIMIT 1" 
    ")," 
    " ?" 
    ")"; 
相關問題