Deleting an array works on CodeBlocks but not on Visual - c++

I'm building a class and at some point I call a delete. In codeblocks it works and in Visual Studio 2013 it doesn't.
In my class I have:
private:
bool sign; // 0 if positive, 1 if negative
int NumberSize;
int VectorSize;
int *Number;
Then I have this function:
void XXLint::Edit(const char* s)
{
// Get Size
this->NumberSize = strlen(s);
// Initialise Sign
if (s[0] == '-')
{
this->sign = 1;
s++;
}
else if (s[0] == '+') s++;
else this->sign = 0;
delete[] Number; // Here the debugger gives me the error
//Get Vector Size
this->VectorSize = this->NumberSize / 4;
// Allocate Memory
this->Number = new int[this->VectorSize];
//Store the string into the number vector.
int location = this->VectorSize;
int current = this->NumberSize - 1;
while (location)
{
int aux = 0;
for (int i = 3; i >= 0 && current; i--)
if (current - i >= 0)
aux = aux * 10 + s[current - i] - '0';
current -= 4;
this->Number[location--] = aux;
}
}
I did read the article and it really is interesting :D but i don't belive that's where the error comes from.
Why is this error happening?

Look here:
this->Number = new int[this->VectorSize];
int location = this->VectorSize;
Assume for argument's sake that this->VectorSize == 10. So location now has the value 10. However, later you do this in a loop:
while (location)
{
//...
this->Number[location--] = aux; // out of bounds!
}
You are accessing this->Number[10]. That is a memory overwrite. And no, location doesn't get decremented before it's used, as it is post-decrement, not pre-decrement.
When you compile a program on another compiler and then run the program, if that runtime detects errors, always question your code. It doesn't matter if it "worked" on compiler X, or if it worked on your computer and your friend's computer but not the teacher or customer's computer. Always suspect there is something wrong with your code if there is a failure such as memory corruption.

Related

stoi() terminate after throwing and instance of 'std::invalid argument in c++-- What am I doing wrong?

Fairly new to coding. Trying some of the easy projects at LeetCode, and failing... Ha! I am trying to take an integer and convert it to a string so I can reverse it, then re-convert the reversed string back into a integer.
This code is throwing the "terminate after throwing and instance of 'std::invalid argument' what(): stoi" error. I've spent an hour searching google and other questions here on SO, but can't figure out why it's not working.
bool isPalindrome(int x) {
std::string backwards ="";
std::string NumString = std::to_string(x);
for (int i = NumString.size(); i >= 0 ; i--) {
backwards += NumString[i];
}
int check = std::stoi(backwards);
if (check == x) {
return true;
}
else {
return false;
}
}
EDIT: I think I figured it out. It was adding the null character to the end of the string upon first conversion, then adding it to the beginning of the string when I reversed it. Spaces can't be converted to integers.
So... I changed this line and it works:
for (int i = NumString.size() - 1; i >= 0 ; i--)
you can also reverse number without using string.
bool isPalindrome(int x) {
long long rev = 0;
int cur = x;
while( cur > 0) {
rev *= 10;
rev += cur % 10;
cur /=10;
}
return rev == x;
}
Its simpler than your answer that you edited in. YOu have
for (int i = NumString.size(); i >= 0 ; i--) {
backwards += NumString[i];
}
Imagine that Numstring has length 3 (no matter what spaces, digits,....)
So now you are efectively doing
for (int i = 3; i >= 0 ; i--) {
backwards += NumString[i];
}
So first loop goes
backwards += NumString[3];
well the indexes of things in an array of length 3 in c++ are 0,1,2. YOu are going one off the end
This is why you see loops doing
for(int i = 0; i < len; i++){}
Note the i < len not i <= len

Why does attempting to return in this function cause the program to crash in C++?

I am working through challenges on a site called CodeFights to help me learn C++ and improve my programming. One challenge was to write a program that would find the length of a specific sequence based on the zeroth element:
Element 0: 16
Element 1: 1^2 + 6^2 = 37
Element 2: 3^2 + 7^2 = 58
...
The sequence ends when an element is repeated.
This code is supposed to return the length of the sequence:
#include <cmath>
#include <iostream>
#include <vector>
int squareDigitsSequence(int a0) {
int counter = 0; //Counts number of elements
int temp = 0; //Stores current element
std::vector<int> sequence (1); //Stores sequence
sequence[0] = a0; //Stores first element in sequence
for (int i = 0;; i++) { //Loops until sequence finishes
counter += 1; //Increments counter
temp = 0; //Resets element storage
if (a0 < 10) { //If it is only 1 digit
temp += pow(a0, 2);
}
else if (a0 < 100 && a0 > 9) { //If it is 2 digits
temp += pow(a0 / 10, 2);
temp += pow(a0 % 10, 2);
}
else { //If it is 3 digits
temp += pow(a0 % 10, 2);
temp += pow(((a0 % 100) - (a0 % 10)) / 10, 2);
temp += pow(a0 / 100, 2);
}
for (int b = 0; b < counter; b++) { //Checks if the element has appeared before
if (temp == sequence[b]) {
return counter; //Crashes here.
}
}
sequence[i + 1] = temp; //Stores current element in sequence
a0 = temp; //Moves element to be checked to current element
}
return 0; //Would not accept the function without this
}
int main() {
std::cout << squareDigitsSequence(16);
return 0;
}
Attempting to run this causes the program to crash. I have attempted to debug, and also look for similar problems but no success. Help appreciated.
EDIT: The problem was that I created a vector with size (1), and tried to add more elements to it. Solution use .push_back() instead of [i + 1].
Thanks to everyone that answered, hope this can be useful to others in the future.
The crash is the result of an out-of-bound write in this line:
sequence[i + 1] = temp;
Since the vector is initialized with size 1 and never resized, you overflow the internal buffer and override some arbitrary memory location.
To avoid this problem, use vector::push_back, which will enlarge the vector if the internal buffer isn't large enough.

Assertion Error using a struct vector c++

I have a program where I want to update a variable from a string. The function will read in a string, find if it is addition, subtraction, etc. and then add it to the variable. The function is this:
using namespace std;
struct variable{
string name;
int value;
};
void update_varabile(string line, vector<variable> & v)
{
char c = line[0]; //variable to be updated
string b;
char d[0];
int flag = 0; //counter
int a = 0;
int temp_value = 0;
int perm_value = 0;
for (int i = 0; i < v.size(); i++) {
if (c == v[i].name[0]) {
flag = 1;
temp_value = v[i].value;
break;
}
}
if (flag == 1) { //variable is present
for (int i = 0; i< line.size(); i++) {
if (line[i] == '+'|| line[i] =='-'|| line[i] == '*'|| line[i] =='/') {
b[0] = line[i+1]; //assuming the integer is between 0 and 9
d[0] = b[0];
a = atoi (d);
if (line [i] == '+') {
perm_value = temp_value + a;
} else if (line [i] == '-') {
perm_value = temp_value - a;
} else if (line [i] == '*') {
perm_value = temp_value * a;
} else if (line [i] == '/') {
perm_value = temp_value / a;
}
}
}
for (int i = 0; i < v.size(); i++) {
if (v[i].name[0] == 'c') {
v[i].value = perm_value;
break;
}
}
}
}
The call in main looks like this:
int main()
{
variable a;
int val = 0;
string up = "c=c+2";
string f = "c";
vector<variable> q;
a.name = f;
a.value = val;
q.push_back(a);
update_varabile(up, q);
return 0;
}
However, when I run the code, I get this error message:
Assertion failed: ((m_->valid == LIFE_MUTEX) && (m_->busy > 0)), file C:/crossdev/src/winpthreads-git20141130/src/mutex.c, line 57
Process returned 1 (0x1) execution time : 0.014 s
Press any key to continue.
I have run the debugger line by line and it shows that the function properly executes. I have also tried to look for that C:/ file on my computer and it doesn't exist. Not sure why this isn't working.
First thing first, get rid of all the breaks. Only place breaks should be used in C++ is at the end of each case statement. Makes near impossible to read code with a bunch of breaks, because I have to go down and figure out what each break is there and why. If you need to get out of a for loop early, then use a while loop. you don't need breaks at the end of if and else statements because they cause the program to leave a function early, your if and else statements will naturally skip over if you are using if, else if, and else condition formatting.
Now having said that, you need to break down better what you are trying to do.
example you get a string value like this.
2+3+4-5+6
Your program is going to read from left to right. I am assuming you want it to take the first value which is two and then add three to it then four and so on and so fourth.
The way to do this is first parse the string for int values and then parse the addition and subtraction values. In other words read the int values out of the string untill you hit a value that is not between 0 and 9. Then see if that non-numerical value is an operator you are looking for. This way your program wont trip up on a value like 2555 and 2.
IE
//intValueHolder is a string.
while(i < line.size() && line[i] >= '0' && line[i] <= '9' ) {
intValueHolder.push_back(string[i]);
}
Then when you hit a '+' or something like that put the char value through a case statements. and don't forget to add a default value at the end to account for garbage input like 'a'. You may want to hold the value just incase you need to get your left side value first before you can get your right side value. But it sounded like you start out with a left side value so you really only need to find right and which operator it needs. I'm not going to rewrite your program because this looks like an assignment for school. But I will point you in the right direction. Let me know, if I was off on understanding your question.
You may also want to look into using queues for this, if you are not being restricted to just strings and vectors.

C++: delete strange behaviour

I have started doing some stuff with dynamic allocation in C++ but I had some problems. Here's the code:
nrMare(char cifS[], char* startPos = new char())
{
n = 0;
int i;
cif = startPos;
printf("%p %i\n", cif, (cif - (char*)NULL) % 8);
for(i = strlen(cifS) - 1; i >= 0; i--)
{
cif--;
n++;
cif = new(cif) char(cifS[i] - '0');
}
}
~nrMare()
{
int i;
for(i = 0; i < n; i++)
{
delete(cif);
cif++;
}
n = 0;
cif = 0;
}
nrMare is a class (it comes from bigNumber in Romanian :D) which is supposed to be able to contain the digits of a big number.
The problem is that the destructor (~nrMare) gives a weird error, when I make a variable nrMare something() on my computer, but it works for 116 digits long ones.
Do you have any suggestion or explainations?
EDIT: cif is a (char*) type
EDIT #2: n is the length of the number. I use the char pointer this way because I want to be able to add (like n++; cif--; cif = new(cif) char(number_to_add); -> this would add number_to_add in the left side of cif) and draw elements from both sides.
EDIT #3: this is gonna be a long one... Sorry for being such a bad explainer and thanks for your patience.here are some operators:
void operator-=(nrMare nr2)
{
int i;
for(i = 1; i <= n && i <= nr2.n; i++)
cif[n - i] -= nr2[nr2.n - i];
for(i = n - 1; i >= 0; i--)
{
if(cif[i] < 0)
{
cif[i] += 10;
cif[i - 1]--;
}
}
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
}
int operator/=(int nr)
{
int i;
for(i = 0; i < n - 1; i++)
{
cif[i + 1] += (cif[i] % nr) * 10;
cif[i] = cif[i] / nr;
}
i = cif[n - 1] % nr;
cif[n - 1] /= nr;
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
return i; // the return value is this big number % nr
}
void operator*=(int cifTimes)
{
int i;
for(i = 0; i < n; i++)
{
cif[i] *= cifTimes;
}
for(i = n - 1; i >= 0; i--)
{
if(cif[i] > 9)
{
if(i != 0)
{
cif[i - 1]++;
cif[i] %= 10;
}
else
{
n++;
cif[0] %= 10;
cif--;
cif = new(cif) char(cif[0] = 1);
}
}
}
}
EDIT #4: n = length of the number = number of digits = number of bytes. Weird error means it just crashes. I don't know how to find more about it. MinGW compiler asks Visual Studio (Visual C++) to debug it because it has some problems. This is for a problem, and somewhere (in the evaluator) it says "Killed by signal 6(SIGABRT)", if this helps.
EDIT #...: #Branko Dimitrijevic: I don't wanna be lazy... I want my own... I had this problem in more attempts to make something running. If I take out the destructor, it works just fine, just I guess then it would be a memory leak that way... I really want to find out why would this occur... and only for specific sizes and, i.e. it doesn't crash on the first "delete", but on the 11'th in my case, that's why it's weird .
The delete can only work correctly on an address that is at the beginning of a dynamically-allocated block.
The cif will fail one or both of these conditions, leading to undefined behavior when the destructor calls delete, for following reasons:
You assign startPos to cif and then modify it in a very strange way before calling the placement new. So even if startPos is a properly allocated block of dynamic memory, the cif no longer points to the starting address of it.
If the caller passes an address of a stack-based variable to startPos, then you no longer deal with dynamic memory at all.
Not to mention that you call new and delete in a loop - what's up with that? There is also a fair chance for bombarding the memory unless you craft your input parameters in a very specific way. This whole block of code looks suspicious, what exactly are you trying to do?

Access Violation Reading Location

I have a problem with VC++, simply, I hate it haha. My code seems to be running all fine on my Mac but when I try to run it in VC++, I get this error in debug:
Windows has triggered a breakpoint in Assignment1-FINAL.exe.
This may be due to a corruption of the heap, which indicates a bug in
Assignment1-FINAL.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while
Assignment1-FINAL.exe has focus.
I know for a fact I haven't pressed F12 so I am not sure why I am getting this... Then, when I try to run it in Release mode, I get this:
Unhandled exception at 0x00401473 in Assignment1-FINAL.exe:
0xC0000005: Access violation reading location 0x00347015.
This is the code I am using:
int countPointsAboveThreshold(point * points, double threshold_distance) {
int i = 1;
int count = 0;
while (points[i - 1].end != true) {
point pointOne = points[i -1];
point pointTwo = points[i];
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (pointTwo.end == true) {
if (distance > threshold_distance) {
count++;
return count;
} else {
return count;
}
} else if (distance > threshold_distance) {
count++;
}
i++;
}
return count;
}
int totalPoints(point * points) {
int i = 0;
while (points[i].end != true) {
i++;
}
return i + 1;
}
point * findLongPaths(point * points, double threshold_distance) {
int i = 1;
int locationToStore = 0;
int pointsAboveThreshold = countPointsAboveThreshold(points, threshold_distance);
point * pointsByThreshold = new point[pointsAboveThreshold];
pointValues * pointsToCalculate = new pointValues[pointsAboveThreshold];
while (points[i - 1].end != true && i < pointsAboveThreshold) {
point pointOne = points[i - 1];
point pointTwo = points[i];
//Check to see if the distance is greater than the threshold, if it is store in an array of pointValues
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (distance > threshold_distance) {
pointsToCalculate[i - 1].originalLocation = i - 1;
pointsToCalculate[i - 1].distance = distance;
pointsToCalculate[i - 1].final = pointTwo;
pointsToCalculate[i - 1].stored = false;
//If the final point has been calculated, break the loop
if (pointTwo.end == true) {
pointsToCalculate[i].end = true;
break;
} else {
pointsToCalculate[i - 1].end = false;
i++;
continue;
}
}
}
if (points[0].end == true && pointsAboveThreshold == 0) {
point emptyPoint;
emptyPoint.x = 0.0;
emptyPoint.y = 0.0;
emptyPoint.end = true;
pointsByThreshold[0] = emptyPoint;
return pointsByThreshold;
}
//Find the point with the lowest distance
int j = 2;
//EDITED
pointValues pointWithLowest;
pointWithLowest = pointsToCalculate[0];
while (pointsToCalculate[j - 1].end != true) {
for (int k = 1; pointsToCalculate[k - 1].end != true; k++) {
if (pointsToCalculate[k - 1].stored == true) {
k++;
continue;
} else {
if (pointsToCalculate[k - 1].distance > pointWithLowest.distance) {
pointWithLowest = pointsToCalculate[k - 1];
k++;
continue;
} else if (pointsToCalculate[k - 1].distance == pointWithLowest.distance) {
if (pointWithLowest.originalLocation < pointsToCalculate[k - 1].originalLocation) {
pointWithLowest = pointsToCalculate[k - 1];
k++;
continue;
} else {
k++;
continue;
}
} else {
pointWithLowest.stored = true;
pointsByThreshold[locationToStore] = pointWithLowest.final;
locationToStore++;
break;
}
}
}
//DEBUGGER STOPS HERE
j++;
}
delete[] pointsToCalculate;
return pointsByThreshold;
}
And this is the main function:
point *longest_calculated = findLongPaths(p, 1.1);
std::cout << "Should equal " << longest[1].y << ": " << longest_calculated[1].y;
delete longest_calculated;
cin.get();
return 0;
Inital thoughts:
Where's the asserts? Your accessing Points* in countPointsAboveThreshold() as an array, but do no bounds checking at all to make sure you aren't pass the array's end. This would be my first area of checking for memory stomping action. Also, straight pointer calls are very C. Heck, you aren't check bounds in any of your array calls. Dangerous...
Newing arrays of length 0 may or may not be safe. I'd be careful of that.
Heck anytime I see [i - 1] in a statement I get nervous. Very easy to read garbage at i == 0
i,j,k loops with quadrouple nested ifs mixed with continues and a break? No. Rethink that logic. It is way, WAY too complicated.
You are early returning with memory allocated in pointsToCalculate[]. Memory leak there.
Might I suggest breaking your last function into multiple parts to simplify the logic?
Man I hate K&R style brackets. Your choice though - not here to start that holy war :P
Beyond that, I'd go with my first suggestion and make sure that your end bool is set always and that you aren't going out of bounds. As previously suggested, stl::vector and a few references (preferably const) are your friend here.
You posted this as C++ but it seems to be using very little of what C++ actually is all about: objects. This code reads much more like C.
Just some notes:
With C++ you don't need to do typedef struct {...} point, doing struct point {...} does what you are trying to do.
If you use a stl::vector instead of a c-array then your loops will become much simpler and you won't need your function totalPoints(). You can also get rid of the member variable end from point and pointValues
You are creating a lot of variables on the heap rather than on the stack for no good reason. With stl::vector (or other standard containers), local variables, and references you can greatly simplify your memory management and avoid strange crashes such as these.
I'll take a deeper look at your code and see if I can give you some more specific guidance but you really should do some further reading into what C++ provides over C. I'd take a look at cplusplus.com and the C++ FAQ. There are also some excellent book suggestions here.
This part of your code sounds odd to me:
if (distance > threshold_distance) {
pointsToCalculate[i - 1].originalLocation = i - 1;
pointsToCalculate[i - 1].distance = distance;
pointsToCalculate[i - 1].final = pointTwo;
pointsToCalculate[i - 1].stored = false;
...
I think you need to use another index variable (other than i - 1) to populate pointsToCalculate!
I would rewrite this part something like this:
int i = 1;
int index = 0;
// if points[i - 1].end is true how you could access points[i] ?
while (points[i].end != true && i < pointsAboveThreshold) {
point pointOne = points[i - 1];
point pointTwo = points[i];
//Check to see if the distance is greater than the threshold, if it is store in an array of pointValues
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (distance > threshold_distance) {
pointsToCalculate[index].originalLocation = i - 1;
pointsToCalculate[index].distance = distance;
pointsToCalculate[index].final = pointTwo;
pointsToCalculate[index].stored = false;
++ index;
}
++i;
}
pointsToCalculate[index].end = true;
** Also note that you need at least two points in your array or you get access violation again, so you need to check for this and you have the same problem in "countPointsAboveThreshold" function that you need to fix too.
Please check for syntax and typos ;)
But any way I strongly recommend following two last post recommendations too.