【发布时间】:2021-12-01 19:13:54
【问题描述】:
当我尝试在不同于 Visual Studio Code 的任何 IDE 中编译我的代码时,我在读取文件后立即收到以下错误:
free():在 tcache 2 中检测到双重空闲。
当我删除析构函数时,程序运行良好,但“排序”函数将所有行输出为 [(0,0),(0,0)]。我不知道为什么会这样。如前所述,在 Visual Studio Code 中,程序从一开始就运行良好。这个问题有什么解决办法吗?我错过了什么吗?
这是我的代码和我正在使用的文件:
main.cpp
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <iomanip>
#include "Line.hpp"
#include "Point.hpp"
using namespace std;
void inputLines(string filename, vector <Line>& Lines){
ifstream inFS;
inFS.open(filename);
// checking if opened
if (!inFS.is_open()){
cout << "Couldn't open the input file" << endl << endl;
return;
}
//lines:
char letter1, letter2, letter3, letter4, letter5, letter6, d1;
inFS >> letter1 >> letter2 >> letter3 >> letter4 >> letter5 >> letter6>> d1;
//{[line1:[102.0,0.9],[97.0,1.0]],
char d2, letterl, letteri, lettern, lettere, letter_1, d3, d4,d5 ,d6 ,d7 ,d8 ,d9 ,d10 ,d11 ,d12;
double linep1x, linep1y, linep2x, linep2y;
while (!inFS.eof()){
inFS >> d2 >> letterl >> letteri >> lettern >> lettere >> letter_1 >> d3 >> d4
>> linep1x >> d5 >> linep1y >> d6 >> d7 >> d8 >> linep2x >> d9 >> linep2y >> d10 >> d11 >> d12;
if(!inFS.fail() && d2 == '[' && letterl == 'l' && letteri == 'i' && lettern == 'n' && lettere == 'e' && d3 == ':' && d4 == '[' && d5 == ','
&& d6 == ']' && d7 == ',' && d8 == '[' && d9 == ',' && d10== ']' && d11 == ']' ){
Lines.push_back(Line(linep1x,linep1y,linep2x,linep2y));
}
}
inFS.close();
}
bool parallel(Line& line1, Line& line2){
double slope1 = line1.getSlope();
double slope2 = line2.getSlope();
if(slope1 == slope2){
return true;
}
return false;
}
int main (){
cout <<"\n-----------------------------------------------\n"<< " Starting unit testing ... " << "\n-----------------------------------------------\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing setters and getters functions: | ----------\n\n";
Line l1_setGet;
cout << "We want to set a line with the coordinates (1,1)(2,2) and set the slope as 1.0 and the length as 1.41 \n\n";
Point p1_setGet(1,1);
Point p2_setGet(2,2);
l1_setGet.setPoint_1(p1_setGet);
l1_setGet.setPoint_2(p2_setGet);
l1_setGet.setSlope(1);
l1_setGet.setLength(1.41);
assert(l1_setGet.getLength() == 1.41);
assert(l1_setGet.getSlope() == 1);
cout << "All test passed...\n\n";
cout << "Line: " ; l1_setGet.print() ; cout << "\nSlope: " << l1_setGet.getSlope() << "\nLength: " << l1_setGet.getLength() <<"\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing null constructors and assigning constructor: | ----------\n\n";
Point p1_constructor(-32.4,22.4);
Point p2_constructor(44.2,-31.9);
Line l1_constructor;
Line l2_constructor(p1_constructor, p2_constructor);
cout << "We want the first line to be initialized by the null constructor and the second line to be set by the other constructor \n\n";
cout << "Line 1: \n ";
l1_constructor.print(); cout << "\n\n";
cout << "Line 2: [initialized with (-32.4,22.4) and (44.2, -31.9)] \n ";
l2_constructor.print(); cout << "\n\n";
cout << "Let's also test how the constructor calculates the length and the slope. For the second line the slope would be (-0.7) and the length would be (93.9):\n\n";
cout << "Slope: " << l2_constructor.getSlope() << "\n";
cout << "Length: " << l2_constructor.getLength() << "\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing copy constructor and copy assignment operator: | ----------\n\n";
Point p1_copy(27.2,-29.3);
Point p2_copy(45.2, 11.9);
cout << "These are our test cases: \n\n";
Line l1_copy(p1_copy, p2_copy);
Line l3_copy;
cout << " Line 1: "; l1_copy.print(); cout << "\n";
cout << " Line 3: "; l3_copy.print(); cout << "\n\n";
cout << "Let's create and initialize the second line with the first line to test the copy constructor:\n\n";
Line l2_copy(l1_copy);
cout << " Line 2: "; l2_copy.print() ; cout << "\n\n";
cout << "Let's now use the assignment operator (=) to assign the second line to the third line:\n\n";
l3_copy = l2_copy;
cout << " Line 3: "; l3_copy.print() ; cout << "\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the parallel function: | ----------\n\n";
Point p1_para(2.0, 46.4);
Point p2_para(4.0, 88.8);
Point p3_para(2.0, 52.4);
Point p4_para(4.0, 94.8);
Point p5_para(2.0, -32.4);
Point p6_para(4.0, -74.8);
cout << "These are our test cases: \n\n";
Line l1_para(p1_para,p2_para);
Line l2_para(p3_para,p4_para);
Line l3_para(p5_para,p6_para);
cout << " Line 1'slope: " << l1_para.getSlope(); cout << "\n";
cout << " Line 2'slope: " << l2_para.getSlope(); cout << "\n";
cout << " Line 3'slope: " << l3_para.getSlope(); cout << "\n\n";
cout << "Two lines are parallel when they have the same slope. Let's test the parallel function:\n\n";
cout << "Let's see if Line 1 and Line 2 are parallel: \n\n";
parallel(l1_para,l2_para) == 1 ? cout << "They are parallel\n\n" : cout << "They are not parallel\n\n";
assert(parallel(l1_para,l2_para) == 1);
cout << "Let's see if Line 1 and Line 3 are parallel: \n\n";
parallel(l1_para,l3_para) == 1 ? cout << "They are parallel\n\n" : cout << "They are not parallel\n\n";
assert(parallel(l1_para,l3_para) == 0);
cout << "All tests passed...\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the overloaded operators (< > ==): | ----------\n\n";
Point p1_oper(2, 2);
Point p2_oper(4, 4);
Point p3_oper(2, 2);
Point p4_oper(5, 5);
Point p5_oper(2, 2);
Point p6_oper(5, 5);
Point p7_oper(2, 2);
Point p8_oper(6, 6);
cout << "These are our test cases: \n\n";
Line l1_oper(p1_oper,p2_oper);
Line l2_oper(p3_oper,p4_oper);
Line l3_oper(p5_oper,p6_oper);
Line l4_oper(p7_oper,p8_oper);
cout << " Line 1: " ; l1_oper.print(); cout << " Length; " << l1_oper.getLength() <<"\n";
cout << " Line 2: " ; l2_oper.print(); cout << " Length; " << l2_oper.getLength() <<"\n";
cout << " Line 3: " ; l3_oper.print(); cout << " Length; " << l3_oper.getLength() <<"\n";
cout << " Line 4: " ; l4_oper.print(); cout << " Length; " << l4_oper.getLength() <<"\n\n";
cout << " Let's test (<): \n\n";
cout << "(Line 1 < Line 2): ";
l1_oper < l2_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l1_oper < l2_oper == true );
cout << "(Line 2 < Line 1): ";
l2_oper < l1_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper < l1_oper == false );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " Let's test (>): \n\n";
cout << "(Line 2 > Line 3): ";
l2_oper > l3_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper > l3_oper == false );
cout << "(Line 4 > Line 1): ";
l4_oper > l1_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l4_oper > l1_oper == true );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " Let's test (==): \n\n";
cout << "(Line 2 == Line 3): ";
l2_oper == l3_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper == l3_oper == true );
cout << "(Line 1 == Line 4): ";
l1_oper == l4_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l1_oper == l4_oper == false );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << "All tests passed...\n\n";
cout << " ---------- | Testing the file reader function: | ----------\n\n"; //--------------------------------------------------------------------
vector <Line> Lines;
string filename = "lines.txt";
cout << "Reading file...\n\n";
inputLines(filename, Lines);
cout << "Outputting extracted coordinates out of the file: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
cout << " ---------- | Testing the sort function: | ----------\n\n"; //--------------------------------------------------------------------
Lines.clear();
string filename_2 = "lines_2.txt";
cout << "Reading file with non-sorted values...\n\n";
inputLines(filename_2, Lines);
cout << "Outputting extracted coordinates out of the file: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
cout << "Sorting... \n\n";
sort(Lines.begin(), Lines.end());
cout << "Outputting sorted values: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
//----------------------------------------------------------------------------------------------------------------------------------------
Line l1_cout(1,2,3,4);
cout << "Overloading \"cout\" to print an object (in this case, a line with the coordinates (1,2),(3,4): \n\n";
cout << l1_cout << endl;
cout << endl;
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the insertion operator (>> cin): | ----------\n\n";
Line l1_cin;
cout << "Enter a line in the format [(x1,y1),(x2,y2)] " << endl << endl;
cin >> l1_cin;
cout << "\nYou entered: " << endl << endl;
cout << "------- ";
l1_cin.print();
cout << " -------\n\n";
return 0;
}
Line.hpp
#include <cmath>
#include "Point.hpp"
#include <iomanip>
using namespace std;
#ifndef LINE_H
#define LINE_H
class Line{
private:
Point* p1;
Point* p2;
double slope;
double length;
public:
Line(); //null constructor
Line(Point p1, Point p2);
Line(double linep1x, double linep1y, double linep2x, double linep2y);
// !accessors and mutators
//---------------------------------------//
void setPoint_1 (double x, double y){
p1->setX(x);
p1->setY(y);
calculateLength();
calculateSlope();
}
void setPoint_1 (Point p){
*p1=p;
calculateLength();
calculateSlope();
}
Point getPoint_1() const{
return *p1;
}
//---------------------------------------//
void setPoint_2 (double x, double y){
p2->setX(x);
p2->setY(y);
calculateLength();
calculateSlope();
}
void setPoint_2 (Point p){
*p2=p;
calculateLength();
calculateSlope();
}
Point getPoint_2() const{
return *p2;
}
//---------------------------------------//
void setSlope(double s){
this->slope = s;
}
void calculateSlope(){
slope = ( (p2->getY()) - (p1->getY()) ) / ((p2->getX()) - (p1->getX()) );
}
double getSlope() const{
return this->slope;
}
//---------------------------------------//
void setLength(double l){
this->length = l;
}
void calculateLength(){
length = sqrt( (pow( ( (p2->getX()) - (p1->getX()) ) , 2) ) + (pow(( (p2->getY()) - (p1->getY())), 2 ) ) );
}
double getLength() const{
return this->length;
}
//---------------------------------------//
//!print
void print() const;
//!destructor
~Line();
//!copy constructor
Line(const Line& l);
//!assignment
Line& operator=(const Line& line);
//! overloading operators
bool operator==(const Line& line);
bool operator<(const Line& line);
bool operator>(const Line& line);
friend ostream& operator<<(ostream& out, Line& L);
friend istream& operator>>(istream& in, Line& L);
};
#endif
Line::Line(){ //*null constructor
slope = 0;
length= 0;
p1 = new Point();
p2 = new Point();
}
Line::Line(double linep1x, double linep1y, double linep2x, double linep2y){
p1 = new Point ;
p2 = new Point ;
p1->setX(linep1x);
p1->setY(linep1y);
p2->setX(linep2x);
p2->setY(linep2y);
//The distance between two points is given by d(P, Q) = √(x2 − x1)² + (y2 − y1)²
calculateLength();
//The slope of a line, given two points, is defined as m = (y2-y1)/(x2-x1)
calculateSlope();
}
Line::Line(Point point1, Point point2){ //*overload constructor to calculate length and slope
double x1 = point1.getX();
double y1 = point1.getY();
double x2 = point2.getX();
double y2 = point2.getY();
p1 = new Point(x1,y1);
p2 = new Point(x2,y2);
//The distance between two points is given by d(P, Q) = √(x2 − x1)² + (y2 − y1)²
calculateLength();
//The slope of a line, given two points, is defined as m = (y2-y1)/(x2-x1)
calculateSlope();
}
//*destructor
Line::~Line(){
delete p1;
delete p2;
}
//*copy constructor
Line::Line(const Line& line){
this->p1 = new Point ;
this->p2 = new Point ;
this->p1 = line.p1;
this->p2 = line.p2;
length = line.length;
slope = line.slope;
}
//*assignment operator
Line& Line::operator=(const Line& line){
if(this!=&line){
delete this->p1;
delete this->p2;
this->p1 = new Point ;
this->p2 = new Point ;
this->p1 = line.p1;
this->p2 = line.p2;
}
return *this;
}
// * =
bool Line::operator==(const Line& line){
if(this->length == line.length){
return true;
}
return false;
}
//* < operator
bool Line::operator<(const Line& line){
if(this->length < line.length){
return true;
}
return false;
}
//* > operator
bool Line::operator>(const Line& line){
return (!(this->length < line.length) && !(this->length == line.length));
}
// * << operator (cout)
ostream& operator<<(ostream& out, Line& L){
out << "[(" << (L.p1->getX()) << ", " << (L.p1->getY()) <<"), (" << L.p2->getX() << ", " << (L.p2->getY()) <<")]";
return out;
}
// * >> operator (cin)
istream& operator>>(istream& in, Line& L){
char d1, d2, d3, d4, d5, d6, d7, d8, d9;
double x1, y1, x2, y2;
//[(x1,y1),(x2,y2)]
in >> d1 >> d2 >> x1 >> d3 >> y1 >> d4 >> d5 >> d6 >> x2 >> d7 >> y2 >> d8 >> d9;
if(!(d1 == '[' && d2 == '(' && d3 == ',' && d4 == ')' && d5 == ',' && d6 == '(' && d7 == ',' && d8 == ')' && d9 == ']' )){
cout << "Invalid format" << endl;
}
else{
L.setPoint_1(x1,y1);
L.setPoint_2(x2, y2);
}
return in;
}
//* print function
void Line::print() const{
cout << fixed << setprecision (1) << "[" << "(" << p1->getX() <<", " << p1->getY() << ")" << "," << "(" << p2->getX() << ", " << p2->getY() << ")" << "]" ;
}
Point.hpp
#include <cmath>
#include <string>
using namespace std;
#ifndef POINT_H
#define POINT_H
class Point{
private: // can only be used by public
double x;
double y;
public:
///constructor
Point (double X=0, double Y=0) : x(X), y(Y) {}
//functions
void setX(double x) {this->x= x ;}
double getX() const {return this->x ;}
void setY(double y) {this->y=y ;}
double getY() const {return this->y ;}
void print() const;
friend bool operator== (Point lhp, Point rhp);
friend bool operator> (Point lhp, Point rhp);
friend bool operator< (Point lhp, Point rhp);
};
void Point::print() const{
cout << "(" << this->x<< ","<<this->y<<")" << endl;
}
bool operator== (Point lhp, Point rhp){
if((lhp.x == rhp.x && lhp.y == rhp.y)){
return true;
}
else{
return false;
}
}
bool operator> (Point lhp, Point rhp){
int euclideanLeft, euclideanRight;
euclideanLeft = sqrt((pow(lhp.x, 2))+(pow(lhp.y,2)));
euclideanRight = sqrt((pow(rhp.x, 2))+(pow(rhp.y,2)));
if((euclideanLeft > euclideanRight)){
return true;
}
else{
return false;
}
}
bool operator< (Point lhp, Point rhp){
return !((lhp.x > rhp.x, lhp.y > rhp.y) || (lhp.x == rhp.x, lhp.y == rhp.y));
}
#endif
lines.txt
lines:
{
[line1:[102.0,0.9],[97.0,1.0]],
[line2:[103.0,0.8],[98.0,1.0]],
[line3:[104.0,0.7],[99.0,1.0]],
[line4:[105.0,0.6],[100.0,1.0]]
}
lines_2.txt
lines:
{
[line2:[103.0,0.8],[98.0,1.0]],
[line1:[102.0,0.9],[97.0,1.0]],
[line4:[105.0,0.6],[100.0,1.0]],
[line3:[104.0,0.7],[99.0,1.0]]
}
【问题讨论】:
-
Point* p1; Point* p2;-- 为什么是这些指针?看起来你在不存在任何问题时创造了一个问题。为什么这些不是简单的Point p1; Point p2;? -
欢迎来到 SO。看起来这里的大部分代码都是用于测试的。您应该删除所有这些并专注于问题。阅读如何创建minimal reproducible example。
-
我正在使用指向类 Point 的指针,因为它是我作业的一部分。不过感谢大家的反馈。 “(a) 将私有数据成员 p1 和 p2 定义为指向 Point 对象(我们在讲座中使用的对象)的指针,将斜率和长度定义为双变量。”
标签: c++ oop runtime-error