2012-05-13 139 views
1
#include <iostream> 
#include <string.h> 
using namespace std; 

void newBuffer(char* outBuffer, size_t sz) { 
    outBuffer = new char[sz]; 
} 

int main(void) { 

    const char* abcd = "ABCD"; 
    char* foo; 
    foo = NULL; 
    size_t len = strlen(abcd); 
    cout<<"Checkpoint 1"<<endl; 
    newBuffer(foo, len); 
    cout<<"Checkpoint 2"<<endl; 

    cout<<"Checkpoint 2-A"<<endl; 
    memset(foo, '-', len); 
    cout<<"Checkpoint 3"<<endl; 
    strncpy(foo, abcd, len); 
    cout<<"Checkpoint 4"<<endl; 
    cout << foo << endl; 

    int hold; 
    cin>>hold; 
    return 0; 

}訪問衝突寫入位置0x00000000。 memset的函數發出

這個程序檢查點2-1和3它所試圖做是設置字符數組FOO爲char之間崩潰「 - 」,但它失敗,因爲一些訪問的問題。我不明白爲什麼會發生這種情況。非常感謝您提前!

+0

除非這是一個玩具/教育問題:爲什麼你應該使用'std :: string'或'std ::矢量'這樣的東西在C++! –

回答

6

newBuffer函數應該接受引用的第一個參數,以便向它提出的函數內部的變化是可見的來電:

void newBuffer(char*& outBuffer, size_t sz) { 
    outBuffer = new char[sz]; 
} 

因爲它是現在,你的new char[sz]結果分配到本地變量outBuffer這只是一個複製變量的調用者的foo,所以當函數返回它就好像什麼都沒發生過(除了你泄漏的內存)。

還你在你所緩衝分配給的ABCD是4.這意味着你可以容納3個字符在緩衝區,因爲一個保留用於NUL終止子在長度的尺寸的問題結束。您需要在某處添加+ 1(我會在調用該函數時執行該操作,而不是在其中,因爲newBuffer不應該專用於C字符串)。 strncpy只有當源字符串足夠短時纔會終止緩衝區,所以在這種情況下,只有幸運的是,在分配了緩衝區後,內存中恰好有0

在完成它之後,請不要忘記delete[] foomain(儘管對於這種尺寸的程序並不重要)。

+0

當!這是微不足道的。我沒有注意到這一點。非常感謝你。 – FrozenLand

2

它失敗,因爲您的newBuffer函數實際上不起作用。修復它的最簡單方法是將聲明更改爲void newBuffer (char *&outBuffer, size_t sz)。在寫入時,新分配的內存地址實際上並未存儲到主的foo中,因爲指針是按值傳遞的。

0

您正在按值傳遞指針。您需要傳遞指針的引用或指針的地址。

也就是說,使用返回值將是我的觀點更好:

char* newBuffer(size_t sz) { 
    return new char[sz]; 
} 

當寫這樣一來,newBuffer功能並沒有真正似乎不划算。你不需要它。您可以直接使用new,這會更清晰。

當然,如果你使用的是C++,那麼這是毫無意義的。你應該使用string,智能指針等。你不應該有任何需要直接呼叫new。一旦你修正了你在這個問題中討論的錯誤,你會遇到問題,你的字符串不是空終止的,並且由於你忘記爲空終止符分配空間,緩衝區太短而不能保存字符串。關於C++的好處之一是你可以避免C中的字符串處理的恐怖。

相關問題