2011-05-22 69 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); 
} 
相关问题