2017-04-30 43 views
0

引用以下資源之後:herehere。所以我可以看到如何正確的方式來做到這一點。然後在閱讀this後,我可以看到我之前的警告是通過將char* "mystring"的類型傳遞給函數的參數來修復的。但是,我仍然得到了一個非常直觀的幾行代碼的錯誤(雖然我沒有碰到某種類型的C++,因此我有一些麻煩)。C++ - 通過函數內存釋放錯誤傳遞char *

TextDocument.h

#ifndef ____TextDocument__ 
#define ____TextDocument__ 

#include <stdio.h> 

class TextDocument { 
    char *text; 
    char *docName; 
public: 
    void SetText(char *otherText); 
    char *GetText(); 
    void SetDocName(char *newName); 
    char *GetDocName(); 
    int GetTextLength(); 
}; 

#endif /* defined(____TextDocument__) */ 

TextDocument.cpp

#include <iostream> 
#include "TextDocument.h" 
#include "string.h" 
using namespace std; 

void TextDocument::SetText(char *otherText){ 

    cout << otherText << endl; 

    if (text != 0) 
     delete text;   //free the memory 

    text = new char[strlen(otherText)+1]; // +1 for the null char 
    strcpy(text, otherText);    //text <- otherText 
} 

char *TextDocument::GetText(){ 
    return text; 
} 

void TextDocument::SetDocName(char *name){ 

    if (docName != 0) 
     delete docName; 

    docName = new char[strlen(name) + 1]; // +1 for the \0 terminator 
    strcpy(docName, name);     // docName <- name 
} 

char *TextDocument::GetDocName(){ 

    return docName; 
} 

int TextDocument::GetTextLength(){ 
    if (text != 0) { 
     return strlen(text); 
    } 
    else return 0; 
} 

的main.cpp

#include <iostream> 
#include "string.h" 
#include "TextDocument.h" 
#include "Folder.h" 

using namespace std; 

int main(void){ 

    TextDocument *sampleDoc; 
    sampleDoc = new TextDocument; 


    sampleDoc->SetText((char *)"some str"); // I have no idea why there is a linker error here. 

    return 0; 
} 

run.sh

g++ *.cpp -o main 
./main 

輸出:

Blakes-MacBook-Pro:data_encapsulation bmc$ sh run.sh 
some str 
main(848,0x7fff7f54b300) malloc: *** error for object 0x8000000000000000: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
run.sh: line 2: 848 Abort trap: 6   ./main 

問題1

爲什麼沒有刪除我的char *文本時,它是自存。

問題2(邊欄的問題,不是我的眼前問題)

哪裏是把所有這些.h文件的最佳地點?例子)我需要#include <iostream>using namespace std在幾個不同的.h或.cpp文件中,哪裏是放置它們的最佳位置;如果你只將它們放在主體中,那麼其他模塊將無法看到它併產生錯誤。

月1日修訂提交

所以這個東西多一些擰緊後,我得到了錯誤與去程從

if (text != 0) 
    delete text;   //free the memory 

轉產到

if (text) 
    delete text;   //free the memory 

我猜我瞭解邏輯if (thestringeisntempty) delete text;,但爲什麼if(text != 0) delete text;不能正常工作?

+1

你的問題是不使用std :: string,但使用高度推薦的新建和刪除。 –

+0

您是否在TextDocument的構造函數中將文本設置爲'NULL'(或'nullptr')?編輯:沒關係,沒有構造函數。 –

+0

@Techel,所以你只需要使用一個'std :: string'數據成員,然後在那裏重置它的值呢?我正在嘗試學習最佳實踐。 – bmc

回答

1

兩個解決方案:

  1. 添加一個構造函數來TextDocument,妥善初始化您的指針。

    TextDocument() : text(nullptr), docName(nullptr) {} 
    

使用NULL,而不是nullptr如果你的編譯器不支持後者。

  1. 拋棄char * s並使用std :: string。
+0

這有效,但我仍然困惑爲什麼我必須初始化'char * text'或'std :: string text'到最初。它就像一塊未初始化的內存,即使是NULL狀態也沒有效果嗎? – bmc

+0

您必須將char *初始化爲已知的內容,以便稍後可以安全地聲明它。這裏的確表示指針當前沒有指向有效的字符。不要將nullptr(=無效指針值)傳遞給std :: string的構造函數,並使用默認構造函數,它將使字符串對象保持'空'狀態。 –