2011-05-22 71 views
2

我正在研究只包含字符數組的類,它的大小(以字節爲單位)。目前,我想爲該類重載'+'操作數(以實現連接)。構造函數工作正常。對象被創建,我可以在調試器中看到它們的字段和值。我被困在使用'+'的地方(main(第13行))。代碼編譯得很好,甚至沒有警告,但是當我運行它時,我的程序因「無效指針消息」失敗。我發現那個無效指針在哪裏。它在'+'實現中(BufferArray.cpp,第39行)。當我調用SetBuffer時,char數組被正確賦值(我在運算符實現範圍中看到它的值爲'qwasd'),但是在下一行時,它在我調用SetSize時消失。我不知道爲什麼。在char數組包裝類中實現C++ setter的正確方法是什麼?

我的setter有什麼問題,在這種情況下如何實現'+'操作數?

在此先感謝。

這裏是我一起工作的代碼:

BufferArray.h:

#include <string.h> 
#include <stdio.h> 

#ifndef BUFFERARRAY_H 
#define BUFFERARRAY_H 
class BufferArray { 
public: 
    BufferArray(char* reservedPlace); 
    BufferArray(); 
    void SetSize(int sz); 
    int GetSize(); 
    void SetBuffer(char* buf); 
    char* GetBuffer(); 
    BufferArray operator+ (BufferArray bArr) const; 
    virtual ~BufferArray(); 
private: 
    int size; 
    char *buffer; 
}; 

#endif /* BUFFERARRAY_H */ 

實施是在未來的文件BufferArray.cpp:

#include "BufferArray.h" 

// Constructors. 
BufferArray::BufferArray(){ 
    size = 0; 
    strcpy(buffer, ""); 
} 
BufferArray::BufferArray(char* reservedPlace) { 
    size = strlen(reservedPlace); 
    buffer = reservedPlace; 
} 

// Getters and setters. 
void BufferArray::SetSize(int sz) 
{ 
    size = sz; 
} 
int BufferArray::GetSize() 
{ 
    return size; 
} 
void BufferArray::SetBuffer(char* buf) 
{ 
    buffer = buf; 
} 
char* BufferArray::GetBuffer() 
{ 
    return buffer; 
} 

// Operator +. 
BufferArray BufferArray::operator+ (BufferArray bArr) const 
{ 
    char tempCharArray[strlen(buffer) + strlen(bArr.GetBuffer())]; 
    strcpy(tempCharArray, buffer); 
    strcat(tempCharArray, bArr.GetBuffer()); 
    BufferArray tempBA; 
    tempBA.SetBuffer(tempCharArray); 
    tempBA.SetSize(strlen(bArr.GetBuffer()) + strlen(buffer)); // Vanishes buffer field. 
    printf("%d",tempBA.GetSize()); 
    return tempBA; 
} 

// Destructor. 
BufferArray::~BufferArray() { 
    // Destroy the pointer. 
    delete [] buffer; 
} 

而且主要功能:

#include <cstdlib> 
#include <iostream> 
#include "BufferArray.h" 
using namespace std; 

int main(int argc, char** argv) { 
    BufferArray ba1; 
    char tmp1[3] = "qw"; 
    char tmp2[4] = "asd"; 
    ba1.SetSize(strlen(tmp1)); 
    ba1.SetBuffer(tmp1); 
    BufferArray ba2(tmp2); 
    BufferArray ba3 = ba1 + ba2;   // Runtime error is here. 
    cout << ba3.GetBuffer() << endl; 
    return 0; 
} 

回答

4

in BufferArray :: operator +,tempCharArray是一個臨時緩衝區,當函數完成時會被銷燬。基本上有兩種方法可以處理這個問題:

1 /在operator +中用new []分配臨時緩衝區,這樣你就可以確保緩衝區能夠存儲對operator +的調用,但是你會有內存泄漏或者稍後需要調用者調用delete [],這是相當笨拙和容易出錯的

2 /或更好的是,修改setBuffer,使其執行緩衝區的內部副本並添加一個調用來刪除[]中的[]自己的析構函數:

BufferArray::~BufferArray() { 
    delete[] buffer; 
} 

void BufferArray::setBuffer(char *otherBuffer) { 
    buffer = new char[strlen(otherBuffer) + 1]; 
    strcpy(buffer, otherBuffer); 
} 

請注意,您必須修改構造函數,因此它同樣將輸入緩衝區(否則你將有一個伊勒當調用對象被銷燬時,調用gal []來刪除[]],然後你可能想重載copy-constructor和賦值操作符以防止淺拷貝,從而導致雙重刪除緩衝區。

在實際的生產代碼中,您希望使用某種託管指針來避免自己刪除(例如std :: vector或boost :: shared_array),但對於作業而言,上述解決方案應該沒問題。

在一個側面說明,別忘了使用時的strlen來確定你的緩衝區的大小添加+1;)

+0

我試着看的時候,「BUF」作爲傳遞什麼樣的strlen(BUF)返回一個輸入參數,並發現它工作正常(它返回5)。感謝您的答案!我正在努力修復我的班級。在工作後我會接受適當的答案。 – 2011-05-22 10:02:31

+0

它的工作原理!除了使用'new'關鍵字創建char數組的setter和構造函數代碼的更改外,我還需要像這樣動態分配BufferArray tempBA:BufferArray * tempBA = new BufferArray(tempCharArray);然後我返回* tempBA,而不是tempBA。 – 2011-05-22 19:12:25

1

您需要使用new來創建這些char數組,否則在退出範圍時會臨時銷燬(如tempBA)。

void BufferArray::SetBuffer(char* buf) 
{ 
    buffer = new char[strlen(buf)+1]; //edit, my size param wasn't necessary 
    strcpy(buffer,buf); 
} 
相關問題