2011-10-12 90 views
4

我現在有什麼似乎是無法解決的EXC_BAD_ACCESS問題。 我試過啓用NSZombie,因爲似乎是許多帖子中的建議,但我正在處理c指針而不是obj c對象,所以我沒有得到任何有用的調試信息。間歇性extaudiofileread exc_bad_access

我的代碼的工作方式是,在它需要事先從磁盤一些音頻I分離一個新的POSIX線程的指針傳遞約我想要的音頻信息。然後我讀了一些樣品。 我在NSThread或NSOperation上選擇posix的原因是因爲它看起來速度更快。我的音頻相當密集,所以我需要儘快讀取音頻。

我該如何解決這個錯誤的訪問錯誤?它不會一直髮生。有時它似乎在應用程序非常繁忙時發生。偶爾它不會發生。

反正我有可能只是拋出一個嘗試捕捉周圍這是一個速戰速決?我還能如何調查這種情況的原因呢?

編輯這是一個單獨的問題,我問一個鏈接,但它關係到同樣的問題

[線程的激烈IO] [1]

//detachnewthread gets called from remoteio callback 

void detachnewthread(AudioSourceOBJ str) 
{ 

    //..... code removed for brevity 
    if(str) 
    { 

     int rc; 

     rc = pthread_create(&str->thread, NULL, FetchAudio, (void *)str); 
     if (rc){ 
      printf("ERROR; return code from pthread_create() is %d\n", rc); 
      exit(-1); 
     } 

    } 

} 


void *FetchAudio(void *threadid) 

{ AudioSourceOBJ soundptr =線程ID;

AudioUnitSampleType *outSamplesChannelLeft; 
AudioUnitSampleType *outSamplesChannelRight; 

outSamplesChannelLeft     = (AudioUnitSampleType *) soundptr->queuebuffer->ABL->mBuffers[0].mData; 
outSamplesChannelRight = (AudioUnitSampleType *)soundptr->queuebuffer->ABL->mBuffers[0].mData; 
// ExtAudioFileRef audioFileRef; 



// result= ExtAudioFileOpenURL(str->path, &str->audioFileObject); 

AudioStreamBasicDescription importFormat = {0}; 

size_t bytesPerSample = sizeof (AudioUnitSampleType); 

// Fill the application audio format struct's fields to define a linear PCM, 
//  stereo, noninterleaved stream at the hardware sample rate. 
importFormat.mFormatID   = kAudioFormatLinearPCM; 
importFormat.mFormatFlags  = kAudioFormatFlagsAudioUnitCanonical; 
importFormat.mBytesPerPacket = bytesPerSample; 
importFormat.mFramesPerPacket = 1; 
importFormat.mBytesPerFrame  = bytesPerSample; 
importFormat.mChannelsPerFrame = 2;     // 2 indicates stereo 
importFormat.mBitsPerChannel = 8 * bytesPerSample; 
importFormat.mSampleRate  = 44100; 


ExtAudioFileSetProperty (
            engineDescribtion.audiofilerefs[soundptr->audioindex], 
            kExtAudioFileProperty_ClientDataFormat, 
            sizeof (importFormat), 
            &importFormat 
            ); 

UInt32 numberofframestoread=(soundptr->amounttoread); 
AudioBufferList *bufferList; 

bufferList = (AudioBufferList *) malloc (
             sizeof (AudioBufferList) + sizeof (AudioBuffer) * (1) 
             ); 


// initialize the mNumberBuffers member 
bufferList->mNumberBuffers = 2; 

// initialize the mBuffers member to 0 
AudioBuffer emptyBuffer = {0}; 
size_t arrayIndex; 
for (arrayIndex = 0; arrayIndex < 2; arrayIndex++) { 
    bufferList->mBuffers[arrayIndex] = emptyBuffer; 
} 

// set up the AudioBuffer structs in the buffer list 
bufferList->mBuffers[0].mNumberChannels = 1; 
bufferList->mBuffers[0].mDataByteSize = numberofframestoread * sizeof (AudioUnitSampleType); 
bufferList->mBuffers[0].mData   = (AudioUnitSampleType*)calloc(numberofframestoread, sizeof(AudioUnitSampleType)); 

    bufferList->mBuffers[1].mNumberChannels = 1; 
    bufferList->mBuffers[1].mDataByteSize = numberofframestoread * sizeof (AudioUnitSampleType); 
    bufferList->mBuffers[1].mData   = (AudioUnitSampleType*)calloc(numberofframestoread, sizeof(AudioUnitSampleType)); 




AudioUnitSampleType *inSamplesChannelLeft=bufferList->mBuffers[0].mData; 
AudioUnitSampleType *inSamplesChannelRight=bufferList->mBuffers[1].mData; 



// UInt32 read=(UInt32)soundptr->fetchsample; 
UInt32 read_plus_half_buffer=soundptr->fetchsample; 

UInt32 readdestination= read_plus_half_buffer+numberofframestoread; 
UInt32 actualsamplesread=0; 

actualsamplesread=numberofframestoread; 


if (readdestination>soundptr->perfectframecount) { 


    UInt32 readinpt1=0; 
    UInt32 readoutpt1=0; 
    UInt32 readinpt2=0; 
    UInt32 readoutpt2=0; 
    Float32 readtillendamount=0; 

    readinpt1=read_plus_half_buffer; 
    readoutpt1=soundptr->perfectframecount; 
    readinpt2=0; 



    if(read_plus_half_buffer>soundptr->perfectframecount) 
    { 
     readtillendamount=numberofframestoread; 
     readinpt1=read_plus_half_buffer-soundptr->perfectframecount; 

    }else 
    { 

     readtillendamount=soundptr->perfectframecount - readinpt1; 
     readoutpt2=numberofframestoread-readtillendamount; 




    } 
    actualsamplesread= readtillendamount; 
    ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], readinpt1); 
    ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&actualsamplesread , bufferList); 

    int writeposition=soundptr->queuebuffer->position; 

    for (int i=0; i<actualsamplesread; i++) { 


     outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[i]; 
     outSamplesChannelRight[writeposition]=inSamplesChannelRight[i]; 



     writeposition++; 

    } 

    if (actualsamplesread!=readtillendamount) { 

     UInt32 newzeroamount= readtillendamount-actualsamplesread; 

     for (int j=0; j<newzeroamount; j++) { 

      outSamplesChannelLeft[writeposition]=0; 
      outSamplesChannelRight[writeposition]=0; 
      writeposition++; 

     } 

    }  
    bufferList->mBuffers[1].mDataByteSize = readoutpt2 * sizeof (AudioUnitSampleType); 
    bufferList->mBuffers[0].mDataByteSize = readoutpt2 * sizeof (AudioUnitSampleType); 


    ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], 0); 
    ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&readoutpt2 , bufferList); 


    for (int k=0; k<readoutpt2; k++) { 

     outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[k]; 
     outSamplesChannelRight[writeposition]=inSamplesChannelRight[k]; 
     writeposition++; 

    } 


}else if(readdestination<=soundptr->perfectframecount){ 

    ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], read_plus_half_buffer); 

    bufferList->mBuffers[1].mDataByteSize = actualsamplesread * sizeof (AudioUnitSampleType); 
    bufferList->mBuffers[0].mDataByteSize = actualsamplesread * sizeof (AudioUnitSampleType); 
    // crash happens here 

    if(bufferList) 
    { 
    assert(ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&actualsamplesread , bufferList)); 
    }else 

    { 
     printf("NO BUFFER"); 
    } 



    int writeposition=soundptr->queuebuffer->position; 
    for (int i=0; i<actualsamplesread; i++) { 

     outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[i]; 
     outSamplesChannelRight[writeposition]=inSamplesChannelRight[i]; 
     writeposition++; 

    } 

    if (actualsamplesread!=numberofframestoread) { 
     int zerosamples=0; 

     zerosamples=numberofframestoread-actualsamplesread; 

     for (int j=0; j<zerosamples; j++) { 
      outSamplesChannelLeft[writeposition]=0; 
      outSamplesChannelRight[writeposition]=0; 
      writeposition++; 


     } 

    }     

}else 
{ 
    printf("unknown condition"); 

} 





free(bufferList->mBuffers[0].mData); 
free(bufferList->mBuffers[1].mData); 
free(bufferList); 
bufferList=nil; 

soundptr->queuebuffer->isreading=NO; 

// pthread_detach(soundptr->thread); 
// free(&soundptr->m_lock); 
return 0; 
// pthread_exit(NULL); 

}

編輯2

O.K我已經想通了如何使用malloc歷史。我有一個很大的跟蹤聲明。這是我第一次在&之前見過類似的東西,我不知道如何用它來幫助自己。

ALLOC 0x6c67000-0x6c67fd7 [size=4056]: thread_a019c540 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | migHelperRecievePortCallout | _XReceivedStatusBarDataAndActions | _UIStatusBarReceivedStatusBarDataAndActions | -[UIStatusBarServer _receivedStatusBarData:actions:] | -[UIStatusBarForegroundView setStatusBarData:actions:animated:] | -[UIStatusBarLayoutManager updateItemsWithData:actions:animated:] | -[UIStatusBarLayoutManager _updateItemView:withData:actions:animated:] | -[UIStatusBarItemView updateContentsAndWidth] | -[UIStatusBarTimeItemView contentsImageForStyle:] | -[UIStatusBarItemView drawText:forStyle:] | -[UIStatusBarItemView drawText:forStyle:forWidth:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:] | drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int) | WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const | WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const | WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const | WebCore::showGlyphsWithAdvances(WebCore::FontPlatformData const&, CGContext*, unsigned short const*, CGSize const*, unsigned long) | CGContextShowGlyphsWithAdvances | draw_glyphs | ripc_DrawGlyphs | ripc_RenderGlyphs | CGGlyphLockLockGlyphBitmaps | create_missing_bitmaps | CGFontCreateGlyphBitmap8 | aa_create | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fd7 [size=4056]: thread_a019c540 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | migHelperRecievePortCallout | _XReceivedStatusBarDataAndActions | _UIStatusBarReceivedStatusBarDataAndActions | -[UIStatusBarServer _receivedStatusBarData:actions:] | -[UIStatusBarForegroundView setStatusBarData:actions:animated:] | -[UIStatusBarLayoutManager updateItemsWithData:actions:animated:] | -[UIStatusBarLayoutManager _updateItemView:withData:actions:animated:] | -[UIStatusBarItemView updateContentsAndWidth] | -[UIStatusBarTimeItemView contentsImageForStyle:] | -[UIStatusBarItemView drawText:forStyle:] | -[UIStatusBarItemView drawText:forStyle:forWidth:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:] | drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int) | WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const | WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const | WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const | WebCore::showGlyphsWithAdvances(WebCore::FontPlatformData const&, CGContext*, unsigned short const*, CGSize const*, unsigned long) | CGContextShowGlyphsWithAdvances | draw_glyphs | ripc_DrawGlyphs | ripc_RenderGlyphs | CGGlyphLockLockGlyphBitmaps | create_missing_bitmaps | CGFontCreateGlyphBitmap8 | aa_destroy | free 

ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b024f000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fff [size=4096]: thread_b024f000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free 

ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0353000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0353000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free 

ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0763000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | CABufferList::AllocateBuffers(unsigned long) | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0763000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | free 

ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0a6f000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | CABufferList::AllocateBuffers(unsigned long) | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0a6f000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | free 

ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0081000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc 
---- 
FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0081000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free 
+0

'似乎執行得更快' - 除非你很快創建線程,我非常懷疑用於創建線程的方法會影響它們的性能。但是,請用一些基準證明我的錯誤;) – deanWombourne

+0

您認爲快速多快?我每秒鐘分離16到24個線程。這是否過度? – dubbeat

+0

我認爲這有點過分,是的。我會考慮重新思考架構 - 用這麼多線程創建線程的成本將超過它們的好處。有什麼可以順序執行的,所以你創建的線程少得多嗎? – deanWombourne

回答

1

我最終找到了解決這個問題的辦法。每次我需要音頻時,我都會創建一個新線程來獲取音頻。當線程正在爲特定的緩衝區獲取音頻時,相同的緩衝區會再次請求數據,從而導致同時訪問相同的緩衝區,即exc_bad_access。

我具有一個線程等待和被髮送信號使用POSIX條件獲取數據解決了這個。

這裏所有的答案都是有用的,幫助我學到了很多關於調試。謝謝你們..

+0

非常好,你有它排序!我一有空,就會看這個。這說我可能不會有太多的幫助,因爲我認爲這很可能是緩衝區大小計算問題。 –

+0

好消息。我建議你將你的答案標記爲已接受,所以它不會出現在沒有答案的列表中...... :) –

0

問題幾乎肯定會發生,因爲你的閱讀記憶你不應該。因此EXC_BAD_ACCESS。最重要的是你的緩衝區大小和你正在閱讀的內存數量都是正確的。例如,如果您嘗試讀取超過緩衝區的值,則會收到錯誤消息。

ExtAudioFileRead,在&readoutpt2值應指定的幀的數量。你確定這個值是正確的嗎? bufferList是否足夠大以存儲該幀數?當你讀數據時,你是否前進了一個指針bufferList,並且你提前的數額是否正確?

您是否正確地根據基礎類型分配內存?例如你的音頻數據是整數還是浮點格式?

基本上,一切都需要添加正確,否則你會吹的地方的緩衝區!其他

一個工具來嘗試跟蹤內存問題是guard malloc。您可以在這裏找到更多信息Enabling the Malloc Debugging Features

+0

是的,我確定readoutpt2的值是correc,我的緩衝區列表也一樣。 – dubbeat

+0

樣本是什麼格式?整數或浮點數?你對緩衝區分配的計算是什麼?有多少個頻道? –

+0

樣本被簽名爲16位整數,2個音頻通道。作爲最好的猜測,你會說這個問題與緩衝區列表有關,而不是從磁盤讀取的實際音頻?如果我同時訪問8個音頻源,一切正常。不僅如此,我得到的錯誤。是否有可能是由於缺乏資源代碼線程沒有充分執行,例如:創建緩衝區 – dubbeat

1

我發現在你的下面幾行代碼:

bufferList = (AudioBufferList *) malloc (
             sizeof (AudioBufferList) + sizeof (AudioBuffer) * (1) 
             ); 
// initialize the mNumberBuffers member 
bufferList->mNumberBuffers = 2; 

您malloc'ing的AudioBufferList有一個AudioBuffer的能力,但後來表明它實際上有兩個。嘗試將該「*(1)」更改爲「*(2)」。

除了這個,你不應該執行的malloc的或ExtAudioFileOpen在線程,因爲這些會佔用時間。如果您可以設法預先執行malloc和ExtAudioFileOpen,並將它們保存在您的文件的結構數組中,您可能會發現性能/穩定性有所提高。

我可能沒有閱讀的代碼完全正確,因爲它看起來像格式有一個小搞砸,但我希望這會有所幫助。

1

您可以通過它定位,並找出爲什麼它是錯的,而不是由一個try/catch解決這個問題。

Guard Malloc可以幫助您識別程序中的許多問題。這是一個可以在Xcode中啓用的診斷選項。當你試圖讀或寫你不擁有的內存時,該選項的目的是失敗,使得程序的哪一部分導致問題比通常更清晰。全部細節:man guardmalloc。第一步是正確所有問題guardmalloc指出。您應該可以在沒有這些問題的情況下運行您的應用程序數小時。

如果你想要異常和運行時檢查,以幫助您識別早期(這是值得你考慮)這些問題,考慮C++而不是C爲您實現。

更新

如果它是一個堆分配是有問題的分配,那麼malloc的記錄可能會幫助你。當啓用malloc日誌並且調試器暫停執行時,只需使用malloc_history即可查看用於分配的調用堆棧。 malloc_history將查找日誌中的地址並轉儲alloc創建的調用堆棧。從那裏,你只需按照你的程序中的分配流程來找出你的錯誤。

+0

我無法使用malloc提供的信息。提供的內存地址顯示了malloc發生的位置。 (不知道這是否與exc_bad_access相關)。我放入一箇中斷點並查看調試器中所有對象的內存地址,但我無法找到與錯誤中地址匹配的對象。 – dubbeat

+0

@dubbeat已更新 – justin

+0

我收到此消息「malloc:使用標準記錄器將磁帶錄製到磁盤。」我在哪裏可以查看已錄製的內容? – dubbeat