我正在处理只包含字符数组的类及其大小(以字节为单位的长度)。目前,我想为这个类重载'+'操作数(实现连接)。构造函数工作正常。创建对象,我可以在调试器中看到它们的字段和值。我被困在使用'+'的位置(主要(第13行))。代码编译得很好,甚至没有警告,但是当我运行它时,我的程序失败了“无效指针消息”。我找到了无效指针的位置。它在'+'实现中(BufferArray.cpp,第39行)。当我调用SetBuffer时,char数组被正确分配(我在运算符实现范围中看到它的值'qwasd'),但是当我调用SetSize时,它在下一行时消失了。我不明白为什么。
我的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;
}
答案 0 :(得分:4)
,tempCharArray是一个临时缓冲区,在函数完成时将被销毁。有两种方法可以解决这个问题:
1 /在operator +中使用new []分配临时缓冲区,这样你就可以确保缓冲区在对operator +的调用中幸存下来但是你要么有内存泄漏,要么调用者稍后调用delete [] ,这是相当笨拙和容易出错的
2 /或更好,修改setBuffer,使其执行缓冲区的内部副本,并在您自己的析构函数中添加对delete []的调用:
BufferArray::~BufferArray() {
delete[] buffer;
}
void BufferArray::setBuffer(char *otherBuffer) {
buffer = new char[strlen(otherBuffer) + 1];
strcpy(buffer, otherBuffer);
}
请注意,您必须修改构造函数,以便它还复制输入缓冲区(否则,当对象被销毁时,您将非法调用delete []),然后您可能需要重载复制 - 构造函数和赋值运算符,以防止浅拷贝,这将导致双重删除缓冲区。
在实际的生产代码中,你想要使用某种托管指针来避免自己进行删除(例如std :: vector或boost :: shared_array),但对于作业,上面的解决方案应该没问题。 / p>
另外,在使用strlen确定缓冲区大小时,不要忘记添加+1;)
答案 1 :(得分: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);
}