我在C ++中编写了一些非常简单的代码来对向量进行一些简单的操作。这是文件vector.h的内容:
#ifndef VECTOR_H_INCLUDED
#define VECTOR_H_INCLUDED
class Vector {
int *coordinates;
int *size;
public:
Vector(int vector_size);
Vector(int*,int);
~Vector();
void print(void);
Vector operator +(Vector);
};
#endif
这是实现(file:vector.cpp):
#include "vector.h"
#include <iostream>
using namespace std;
Vector::Vector(int vector_size) {
coordinates = new int[vector_size];
size = new int;
*size = vector_size;
}
Vector::Vector(int* vector_coordinates, int vector_size){
coordinates = vector_coordinates;
size = new int;
*size = vector_size;
}
void Vector::print(void){
cout << "[";
for (unsigned short int index =0; index<*size; index++){
cout << coordinates[index];
if (index < *size-1){cout << ", ";};
}
cout << "]\n";
}
Vector Vector::operator+ (Vector other) {
Vector temp(*(other.size));
if ((*temp.size)!=(*(this->size))){
throw 100;
}
int* temp_c = new int[*(other.size)];
int* other_c = other.coordinates;
for (unsigned short int index =0; index<*size; index++){
temp_c[index] = coordinates[index] + other_c[index];
}
temp.coordinates = temp_c;
return (temp);
}
Vector::~Vector(){
delete[] coordinates;
delete size;
}
从我的main.cpp中,我执行以下操作:
#include <iostream>
using namespace std;
#include "vector/vector.h"
const int size = 3;
int main() {
int *xxx = new int[size];
xxx[0]=4; xxx[1]=5; xxx[2]=-6;
Vector v(xxx,size);// v = [4, 5, -6]
Vector w(size);// w is a vector of size 3
w = v+v; // w should be w=[8,10,-12]
w.print();
return 0;
}
结果是:
[148836464,5,-6,17,148836384,0,0,17,0,0,0,17,3,0,0,17,0,0,0,17,148836480,0,0 ,17,0,10,-12,135025,0,0,0,0,0,0,0,0,分段错误
如果我从析构函数中删除两行:
delete[] coordinates;
delete size;
一切都按预期工作,程序输出:
[8, 10, -12]
我很感激任何解释......
更新1:我将操作符+方法更改为以下内容,但问题未解决:
Vector Vector::operator+(Vector other) {
int size_of_other = *(other.size);
int size_of_me = *(this->size);
if (size_of_other != size_of_me) {
throw 100;
}
int* temp_c = new int[size_of_me];
int* other_c = other.coordinates;
for (unsigned short int index = 0; index < size_of_me; index++) {
temp_c[index] = coordinates[index] + other_c[index];
}
Vector temp(temp_c,size_of_me);
return (temp);
}
更新2:我注意到使用了运营商:
Vector Vector::operator+(Vector other);
我不会得到理想的结果。使其有效的修改是:
const Vector& Vector::operator+(const Vector& other) {
Vector temp(other.size);
for (unsigned short int index = 0; index < size; index++) {
cout << "("<< index <<") "<<coordinates[index] << "+"
<<other.coordinates[index] << ", "<< endl;
temp.coordinates[index] = coordinates[index] + other.coordinates[index];
}
return (temp);
}
更新3:更新#2后,我收到编译器的警告,我返回本地'temp'。我将我的代码更改为以下内容,完全解决了所有问题并且工作正常(我返回了一个 copy 的temp):
const Vector Vector::operator+(const Vector& other) const{
Vector temp(other.size);
for (unsigned short int index = 0; index < size; index++) {
temp.coordinates[index] = coordinates[index] + other.coordinates[index];
}
return *(new Vector(temp));
}
答案 0 :(得分:3)
您的Vector::operator+
至少有一个错误:
int* temp_c = new int;
...
temp_c[index] =
当您使用一个整数分配时,您正在为temp_c
编制索引。所以你的循环会踩到其他内存,造成不确定的行为。
您还需要定义复制构造函数,以便正确使用Vector
个对象。编译器生成默认的复制构造函数,但默认的复制构造函数通常不适用于包含指针的对象。
这一行:
temp.coordinates = temp_c;
导致内存泄漏,因为它会覆盖先前分配的temp.coordinates
向量。
更新3 :您的代码
return *(new Vector(temp));
虽然它似乎工作,但仍然是内存泄漏。您正在分配新的Vector
,然后编译器调用复制构造函数将其复制到函数的返回值中。没有人delete
你刚刚创建的Vector
对象,所以存在内存泄漏。
解决方案是编写复制构造函数,而不是依赖于编译器生成的默认复制构造函数。你问题的所有其他答案都说了同样的话。您需要为正确的程序执行此操作。
答案 1 :(得分:2)
您的类需要复制构造函数和复制赋值运算符才能正常工作。他们需要的一个重要暗示是析构函数不是{}
。请参阅“Rule of Three”。
为了更好,更现代,您还可以考虑移动构造函数和移动赋值运算符。
答案 2 :(得分:2)
请尝试以下代码:
NULL
,因此任何delete []
调用都不会死得很厉害。...看看:
// VectorImplementation.cpp : Defines the entry point for the console application.
//
#include <iostream>
using namespace std;
class Vector {
int *coordinates;
int size;
public:
Vector();
Vector(int vector_size);
Vector(int*,int);
Vector(const Vector& v);
~Vector();
Vector operator +(Vector);
Vector& operator =(const Vector & other);
void print(void);
};
Vector::Vector() {
coordinates = NULL;
size = NULL;
}
Vector::Vector(int vector_size) {
coordinates = new int[vector_size];
size = vector_size;
}
Vector::Vector(int* vector_coordinates, int vector_size){
coordinates = vector_coordinates;
size = vector_size;
}
Vector::Vector(const Vector& v) {
size = v.size;
coordinates = new int[size];
memcpy(coordinates,v.coordinates, sizeof(int)*size);
}
void Vector::print(void){
cout << "[";
for (unsigned short int index =0; index<size; index++){
cout << coordinates[index];
if (index < size-1){cout << ", ";};
}
cout << "]\n";
}
Vector Vector::operator+ (Vector other) {
Vector temp(other.size);
for (unsigned short int index =0; index<size; index++){
temp.coordinates[index] = coordinates[index] + other.coordinates[index];
}
return (temp);
}
Vector & Vector::operator= (const Vector & other)
{
if (this != &other) // protect against invalid self-assignment
{
// 1: allocate new memory and copy the elements
int * tmp_coordinates = new int[other.size];
memcpy(tmp_coordinates, other.coordinates, sizeof(int)*other.size);
// 2: deallocate old memory
delete [] coordinates;
// 3: assign the new memory to the object
coordinates = tmp_coordinates;
size = other.size;
}
// by convention, always return *this
return *this;
}
Vector::~Vector(){
printf("Destructing %p\n", this);
delete[] coordinates;
}
const int size = 3;
int _tmain(int argc, _TCHAR* argv[])
{
int *xxx = new int[size];
xxx[0]=4;
xxx[1]=5;
xxx[2]=-6;
Vector v(xxx,size);// v = [4, 5, -6]
Vector w(size);// w is a vector of size 3
w = v+v; // w should be w=[8,10,-12]
w.print();
return 0;
}
答案 3 :(得分:0)
这样做是个坏主意:
Vector::Vector(int* vector_coordinates, int vector_size){
coordinates = vector_coordinates;
size = new int;
*size = vector_size;
}
将坐标指针指定给未分配的数据,然后尝试在析构函数中删除它。
但是你得到段错误的真正原因是你使用默认的复制构造函数,而v的临时副本会在向量死亡时删除它。您必须实现复制构造函数并确保深度复制或引用计数。
尝试这样的事情:
Vector::Vector(const Vector& other){
size = new int(*other.size);
coordinates = new int[size];
memcpy(coordinates, other.coordinates, sizeof(int)*(*size));
}
此外,如果将const引用作为参数,则运算符+会更有效:
Vector Vector::operator+ (const Vector& other)
答案 4 :(得分:0)
考虑一下
行w = v+v; // w should be w=[8,10,-12]
为v + v的结果构造临时对象,然后将其分配给w并销毁。 由于您没有和赋值运算符,默认实现执行浅拷贝,并且您正在使用释放的内存。
解决此问题的简单方法是在为成员分配内存时实现复制构造函数/赋值运算符和析构函数。