hello I have the following functions:
Block* Keywords::parseBlock(TiXmlElement* element)
{
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
double width = abs(x2 - x1);
int bid = atoi(element->Attribute("id"));
vector<LineElement*> lines;
for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
lines.push_back(parseLine(sub));
return new Block(y2,x2,y1,x1,bid,width, lines);
}///End function parse Block
LineElement* Keywords::parseLine(TiXmlElement* element)
{
double x1 = atoi(element->Attribute("left"));
double y1 = atof(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
vector<Element*> words;
for (TiXmlElement* sub = element->FirstChildElement("word"); sub; sub = sub->NextSiblingElement("word"))
words.push_back(parseWord(sub));
return new LineElement(y2,x2,y1,x1,bid,words);
}///End function parse Line
Element * Keywords::parseWord(TiXmlElement* element)
{
string w =element->Attribute("value");
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
vector<Letter*> chars;
for (TiXmlElement* sub = element->FirstChildElement("char"); sub; sub = sub->NextSiblingElement("char"))
chars.push_back(parseChar(sub));
return new Element(w,y1, x1, y2,x2,-1,bid,chars);
}///End function parse word
Letter * Keywords::parseChar(TiXmlElement* element)
{
string w = element->Attribute("value");
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
return new Letter(w,y1,x1,y2,x2,bid);
}
I think that I have a memory leak, How can I delete the pointer after returning it?
How can I use the destructor to free the memory I am getting a Run-Time error bad:alloc
The easiest way to fix this, like #BalogPal said, is to stop treating C++ like Java. There's no reason to return pointers from any of these functions. Try something like this:
Block Keywords::parseBlock(TiXmlElement* element)
{
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
double width = abs(x2 - x1);
int bid = atoi(element->Attribute("id"));
vector<LineElement> lines;
for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
lines.push_back(parseLine(sub));
return Block(y2, x2, y1, x1, bid, width, lines);
}
LineElement Keywords::parseLine(TiXmlElement* element)
{
double x1 = atoi(element->Attribute("left"));
double y1 = atof(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
vector<Element> words;
for (TiXmlElement* sub = element->FirstChildElement("word"); sub; sub = sub->NextSiblingElement("word"))
words.push_back(parseWord(sub));
return LineElement(y2, x2, y1, x1, bid, words);
}
Element Keywords::parseWord(TiXmlElement* element)
{
string w = element->Attribute("value");
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
vector<Letter> chars;
for (TiXmlElement* sub = element->FirstChildElement("char"); sub; sub = sub->NextSiblingElement("char"))
chars.push_back(parseChar(sub));
return Element(w, y1, x1, y2, x2, -1, bid, chars);
}
Letter Keywords::parseChar(TiXmlElement* element)
{
string w = element->Attribute("value");
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
int bid = atoi(element->Attribute("id"));
return Letter(w, y1, x1, y2, x2, bid);
}
The only reason I left the arguments as pointers is that's what your TiXmlElement's FirstChildElement() and NextSiblingElement() functions return. Normally, I would make them references (TiXmlElement &element) instead, which is even safer, since you can't pass NULL.
If you really need to avoid the copying for performance reasons, and your compiler isn't smart enough to do that automatically, you can use smart pointers, which are reference counted, so you don't need to need to worry about deleteing them.
std::shared_pointer<Block> Keywords::parseBlock(TiXmlElement* element)
{
double x1 = atoi(element->Attribute("left"));
double y1 = atoi(element->Attribute("top"));
double x2 = atoi(element->Attribute("right"));
double y2 = atoi(element->Attribute("bottom"));
double width = abs(x2 - x1);
int bid = atoi(element->Attribute("id"));
vector<std::shared_pointer<LineElement> > lines;
for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
lines.push_back(parseLine(sub));
return std::shared_pointer<Block>(new Block(y2, x2, y1, x1, bid, width, lines));
}
// etc.
You don't generally "return" pointers. You can pass a pointer into the function as a parameter, and assign a value to it in your function. Since a pointer is a memory location, this value will remain in the pointer when your function returns. You can then do any memory management after you have used the pointer for what you want.
Related
I'm a neophyte with c++. I wrote this code but the result for q have to be 1.0, but the code give me, changing the variable's order when I recall function "intercetta", for example -34, 0, 9.75. Why?
#include <iostream>
using namespace std;
float coefficienteAngolare(float x1, float x2, float y1, float y2, float m) {
return m = ((y2 - y1) / (x2 - x1));
}
float intercetta(float m, float x1, float y1, float q) {
return q = y1 - m * x1;
}
int main() {
float x1, x2, y1, y2, m=0, q=0;
x1 = 3.5;
x2 = 6.5;
y1 = 9.75;
y2 = 17.25;
cout << "m= " << coefficienteAngolare(x1, x2, y1, y2, m) << endl;
cout << "q= " << intercetta(x1, y1, m, q) << endl;
}
This function
float coefficienteAngolare(float x1, float x2, float y1, float y2, float m) {
return m = ((y2 - y1) / (x2 - x1));
}
has parameters passed by value. It means that it receives copies of the parameters you give. Whatever you do inside the function, cannot alter the parameters passed to it in main().
If you really want to modify m, you have to pass it by reference
float coefficienteAngolare(float x1, float x2, float y1, float y2, float& m) {
return m = ((y2 - y1) / (x2 - x1));
}
But then, if you modify m, why do you need to return it?
Most probably you either want to not return anything and just store the result in m
void coefficienteAngolare(float x1, float x2, float y1, float y2, float& m) {
m = ((y2 - y1) / (x2 - x1));
}
//....
// in main()
coefficienteAngolare(x1, x2, y1, y2, m);
cout << "m= " << m << endl;
Or you want to return the resulting value, without passing a variable to store it.
float coefficienteAngolare(float x1, float x2, float y1, float y2) {
return ((y2 - y1) / (x2 - x1));
}
//....
// in main()
m = coefficienteAngolare(x1, x2, y1, y2);
cout << "m= " << m << endl;
Along the same line you have to modify intercetta.
Please notice that the order of the parameters is relevant. The compiler cannot guess that the q variable in main() should be the same as the q variable in intercetta, they belong to different scopes.
The variable m (and q) in your main function are different variables than the variables in your other functions. The assignment you have after your return statement assigns a value to a variable which has its lifetime limited to the respective function's scope.
If you want to pass-by-reference, you can do this by declaring the argument as a reference:
float intercetta(float m, float x1, float y1, float& q) {
// ^-------- reference
Fairly strange thing that, I build a search tree and search it. In the search function, if I dynamically allocate memory and delete, memory limit will exceed(I am solving problem in an OJ). But if I just declare an ordinary variable, there is no out of memory issue. Code looks like this:(I recursively search a tree(similar to a 2DTree))
void Search(int x1, int x2, int y1, int y2, node* n, int* st, long long* tem) {
int nx, ny, nx1, nx2, ny1, ny2;
nx = n->x; ny = n->y;
nx1 = n->x1; nx2 = n->x2;
ny1 = n->y1; ny2 = n->y2;
node* l = n->lc;
node* r = n->rc;
if (x1 > nx2 || x2<nx1 || y1>ny2 || y2 < ny1) {
*st = 0;
*tem = 0;
return;
}
else if (x1 <= nx1 && x2 >= nx2 && y1 <= ny1 && y2 >= ny2) {
*st = n->childNum;
*tem = n->tSum;
return;
}
else {
//part with memory issue
long long* tl = new long long;
int* sl = new int;
*tl = 0; *sl = 0;
if (l) Search(x1, x2, y1, y2, l, sl, tl);
*st += (*sl );
*tem += (*tl);
delete tl, sl;
long long* tr = new long long;
int* sr = new int;
if (r) Search(x1, x2, y1, y2, r, sr, tr);
*st += (*sr);
*tem += (*tr);
delete tr, sr;
if (nx >= x1 && nx <= x2 && ny >= y1 && ny <= y2) {
*st += 1;
*tem += n->t;
}
//this goes OK
long long tl = 0;
int sl = 0;
if (l) Search(x1, x2, y1, y2, l, &sl, &tl);
*st += (sl);
*tem += (tl);
long long tr = 0;
int sr = 0;
if (r) Search(x1, x2, y1, y2, r, &sr, &tr);
*st += (sr);
*tem += (tr);
if (nx >= x1 && nx <= x2 && ny >= y1 && ny <= y2) {
*st += 1;
*tem += n->t;
}
}
return;
}
Thanks to #nwp, I realize that this is a trivial problem.
The reason that the original code didn't work is that delete has higher precedence than comma, so delete a, b, c; is the same as (delete a), b, c, so,
delete a,b,c; only deletes a.
Likewise, cin >> a,b; is the same as cin >> a;
check this
First question, I have tried to calculate the expression, di+1=di+2*Δy−2*Δx(yi+1−yi) for the four quadrants. Irrespective of the quadrant, the expression was found to be the same, including signs.
Am I right, or, there has been some mistakes in my calculations (hence, I am wrong)?
Second question, if this expression is only applicable for the first octet, how can I apply this to other octets? To me, there is no way to determine which octet I am working on. Coz, the value of m always represent two opposite octets. For example, if 0<m<1, it represents 1st and 5th octet. Right?
Thirdly, how can we determine the initial/starting value of di?
#include <iostream>
#include "utils.h"
void BresenhamLine(double x1, double y1, double x2, double y2, int color)
{
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
double x = x1;
double y = y1;
double dx = x2 - x1;
double dy = y2 - y1;
double dt = 2 * (dy - dx);
double ds = 2 * dy;
double d = 2*dy - dx;
PlotPixel(x, y, color);
if(dx>=dy)
{
while(x<=x2)
{
x++;
if(d<0)
{
d = d + ds;
}
else
{
y++;
d = d + dt;
}
PlotPixel(x, y, color);
}
}
else
{
while(y<=y2)
{
y++;
if(d<0)
{
x++;
d = d + dt;
}
else
{
d = d + ds;
}
PlotPixel(x, y, color);
}
}
}
int main()
{
int gm = DETECT;
int gd = DETECT;
initgraph(&gm, &gd, "");
double x1 = 0;
double y1 = 0;
double r = 50;
double x2 = 0;
double y2 = 0;
double signx = 0;
double signy = 0;
for(int theta=0 ; theta<=360 ; theta++)
{
x2 = r * cos(DegreeToRad((double) theta));
y2 = r * sin(DegreeToRad((double) theta));
x1 = 5 * cos(DegreeToRad((double) theta));
y1 = 5 * sin(DegreeToRad((double) theta));
BresenhamLine(x1, y1, x2, y2, YELLOW);
}
getch();
closegraph();
return 0;
}
The lines that go through 2nd and 4th quadrant are not showing up.
How to fix that with some minor changes in my code?
With this input: x1: 100 y1: -100 x2: -100 y2: 100
this logic:
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
fails.
This page is a good place to start. It shows code as well for 1 of the octants:
http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
I think you need to swap the x if x1 > x2 and swap the y if y1 > y2 but not swap both if only 1 of those is true.
The external links section of the Wikipedia page contains several links to ready-made implementations that you can study.
Try this:
void BresenhamLine( double x1, double y1, double x2, double y2, int color )
{
const bool steep = (std::abs(y2 - y1) > std::abs(x2 - x1));
if(steep)
{
std::swap(x1, y1);
std::swap(x2, y2);
}
if(x1 > x2)
{
std::swap(x1, x2);
std::swap(y1, y2);
}
double dx = x2 - x1;
double dy = std::abs(y2 - y1);
double error = dx / 2;
int ystep = (y1 < y2) ? 1 : -1;
int y = (int)y1;
int maxX = (int)x2;
for(int x=(int)x1; x<maxX; x++)
{
if(steep)
{
PlotPixel(y, x, color);
}
else
{
PlotPixel(x, y, color);
}
error -= dy;
if(error < 0)
{
y += ystep;
error += dx;
}
}
}
I got this by slightly modifying the code here:http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#C.2B.2B
I tried searching for awnsers, but all the threads are different langs.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
void calcDistance (int x1, int y1, int x2, int y2);
int main()
{
int x1, y1, x2, y2;
cout << "Enter the points in coordinate pair form, ommiting parantheses" << endl;
cin >> x1 >> y1 >> x2 >> y2;
calcDistance (x1, y1, x2, y2);
system("pause");
// how do I cout the dist in main-- says dist isn't declared
}
void calcDistance (int x1, int y1, int x2, int y2)
{
int sideA;
sideA = x2 - x1;
int sideB;
sideB = y2 -y1;
int sideAsqd;
sideAsqd = sideA * sideA;
int sideBsqd;
sideBsqd = sideB * sideB;
int sideCsqd;
sideCsqd = sideAsqd + sideBsqd;
double dist;
dist = sqrt(sideCsqd);
cout << "The calculated distance is "<< dist << endl;
}
How do I make the second cout occur in main. I try just putting it in main, but then I get an error saying that dist is not declared in the scope.
I want to be able to use the dist value in main, while it has been calculated in the function.
Change your function:
double calcDistance (int x1, int y1, int x2, int y2)
{
int sideA = x2 - x1;
int sideB = y2 -y1;
int sideAsqd = sideA * sideA;
int sideBsqd = sideB * sideB;
int sideCsqd = sideAsqd + sideBsqd;
double dist = sqrt(sideCsqd);
return dist;
}
And in main do this:
double res = calcDistance (x1, y1, x2, y2);
cout << "The calculated distance is "<< res << endl;
Given a function, say
void calcDistance (int x1, int y1, int x2, int y2)
{
//...
double dist;
//...
}
The variable dist goes out of scope at the closing brace, so not only can you not refer to it from elsewhere, it won't exist when outside the function.
If you want the value somewhere else, return it:
double calcDistance (int x1, int y1, int x2, int y2)
{
//...
double dist;
//...
return dist;
}
To use it elsewhere just capture the return:
double distance = calcDistance(1,2,3,4);
Now you have another local variable called distance that you can use.
I need to return 3 values. X, Y, Z.
I've tried something like this, but it does not work, can anyone help me a bit? I've looked here: Return a float array in C++ and I tried to do same thing, except with 1 dimensional array to return.
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
float result[3]; // Only works when result is 2 dimensional array, but I need 1 dimension.
public:
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3)
{
myArray[0][0] = x1;
myArray[0][1] = y1;
myArray[0][2] = z1;
myArray[0][3] = r1;
myArray[1][0] = x2;
myArray[1][1] = y2;
myArray[1][2] = z2;
myArray[1][3] = r2;
myArray[2][0] = x3;
myArray[2][1] = y3;
myArray[2][2] = z3;
myArray[2][3] = r3;
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
float* operator[](int i)
{
return result[i]; //Value type does not match the function type
}
const float* operator[](int i) const
{
return result[i]; //Value type does not match the function type
}
};
Instead of returning a pointer, it's usually better practice to accept a pointer and write out the results there. That way someone can allocate a regular array on the stack and have it initialized by your Calculate.
Something like:
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
public:
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3, float *result)
{
myArray[0][0] = x1;
myArray[0][1] = y1;
myArray[0][2] = z1;
myArray[0][3] = r1;
myArray[1][0] = x2;
myArray[1][1] = y2;
myArray[1][2] = z2;
myArray[1][3] = r2;
myArray[2][0] = x3;
myArray[2][1] = y3;
myArray[2][2] = z3;
myArray[2][3] = r3;
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
};
Some other tweaks you can do - separate the constructor from the calculation, since constructors are more for initialization; and pass arrays for safer memory control:
class Calculate
{
float myArray[3][4], originalArray[3][4], tempNumbers[4];
public:
Calculate(const float initArray[3][4])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
myArray[i][j] = initArray[i][j];
}
void DoCalculation(float result[3]) const
{
result[0] = 1;
result[1] = 2;
result[2] = 3;
}
};
int main()
{
float myArray[3][4] =
{
{ 0, 1, 2, 3 },
{ 4, 5, 6, 7 },
{ 8, 9, 0, 1 }
};
float result[3];
Calculate calc(myArray);
calc.DoCalculation(result);
return 0;
}
Another alternative is to make the result as a separate structure and either return it as a value or pass it by reference:
struct Result_Type
{
double values[3];
// Alternatively:
// double x;
// double y;
// double z;
};
// Returning a result
const Result_Type calculate_result_1(/* yada yada yada */)
{
Result_type new_result;
new_result.value[0] = 0;
new_result.value[1] = 0;
new_result.value[2] = 0;
return result; // Return the result as a object
}
// Or passing a result to be modified
void clear_result(Result_Type & any_result) // <-- Note pass by reference
{
any_result.value[0] = 0;
any_result.value[1] = 0;
any_result.value[2] = 0;
return;
}
You may find that this is a preferred design since you can pass around results, modify the Result_Type structure to perform operations with other result vectors (math term). The matrix can also be considered as a composition of result vectors.
This may make the code easier to read also.
result[i] is a float, not a float*, so you can do
const float operator[](int i) const
{
return result[i];
}
But I think you do want to return a reference to get the correct semantics, so you want
const float& operator[](int i) const
{
return result[i];
}
float& operator[](int i)
{
return result[i];
}
Right? (I think this is OK -- it compiles but it's been a while since I've done this...)
In the code, where you are getting an error, you are not trying to return a pointer. You are trying to return a single float at the given index.
Calculate c;
float first = c[0];
float second = c[1];
float third = c[2];
If you meant to return a pointer to the results array, then you would have to return the array, e.g
float* GetResult() { return result; }
It probably doesn't matter much which you'll keep because the end effect is pretty much the same. If you overload operator[], you'll have more control, though, as you can check out-of-bound accesses.
Some responses have indicated the use of pointers. The problem is who allocates that pointer and who frees it. Also one needs to check if the incoming pointer is NULL and so on. Instead I would suggest the following declaration of the constructor.
Calculate(float x1, float y1, float z1, float r1,
float x2, float y2, float z2, float r2,
float x3, float y3, float z3, float r3, float (&r)[3])
This is much more safer as references can not be NULL.