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?
Related
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
There is already a lot about this but none solved my problem or maybe I just didn't understand the answers. I'm just simply trying to return an array from a function
Also, I am having to put all of my functions above the main function that also seems weird to me.
And here is what happens when I try to use pointers:
int * RookMoves(int startingPosition, bool isWhite, int theBoard[64]){
int startingPositionXY[2] = { startingPosition % 8, (startingPosition - (startingPosition % 8)) / 8 };
int possibleRookPositions[14];
int possiblePosXY[2];
int counter = 0;
for (int h = 0; h < 2; h++)
{
int counter2 = 1;
for (int j = 0; j < 2; j++)
{
counter2 *= -1;
for (int i = 1; i < 8; i++)
{
int other = startingPositionXY[h] + (i * counter2);
int hInverted = (h + abs(h - 1)) * abs(h - 1); // 0 + 1 * 1 = 1 but 1 + 0 * 0 = 0
if (other < 8 && other > -1)
{
possiblePosXY[h] = other;
possiblePosXY[hInverted] = startingPositionXY[hInverted];
int movesOneDim = possiblePosXY[0] + (possiblePosXY[1] * 8);
if (CalculateSameColor(isWhite, theBoard[movesOneDim])) {
possibleRookPositions[counter] = movesOneDim;
counter++;
if (CalculateEnemy(isWhite, theBoard[movesOneDim]))
{
break;
}
}
else
{
break;
}
}
else
{
break;
}
}
}
}
for (int i = counter; i < 14; i++) //simply changing any unused elements to -1 for later recognition
{
possibleRookPositions[i] = -1;
}
cout << sizeof(possibleRookPositions) / sizeof(possibleRookPositions[0]) << ' '; // returns 14 just as it should
return possibleRookPositions;
}
int main()
{
int testBoard[64];
for (int i = 0; i < 64; i++) {
testBoard[i] = 0;
}
int* arr = RookMoves(21, true, testBoard);
cout << sizeof(arr) / sizeof(arr[0]); //ouputs: 1, should be 14
}
by all things the web says the pointer one should work but it doesn't, it returns an array with a size of 1.
An array in C++, in “simple” code, is either std::vector or std::array. Those can be returned without any problem. I’d say your issue is that you are writing mostly C and calling it C++. C is IMHO much harder to get right for beginners - so use the fact that you got C++ available for your use!
The C-style arrays is something any professional C++ programmer of course fully understands, but whenever I’m forced to write code like that (due to what amounts to customer requirements), it almost never passes the tests on the first try. So don’t be too worried: even people who can write a compiler that could take this array code and produce assembly output still have trouble with getting it right to some extent. It’s unwieldy and it has almost no place in C++ of today.
I was trying to get sizeof from a pointer because I don't really understand how those work yet but all I needed to do was to use pointers but just initialize the array I was returning as "static." Thanks to MikeCAT
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.
vector<int> add_vectors(const vector<int> &first, const vector<int> &second){
vector<int> result;
int length = 0;
int carry = 0;
int firsts_size = first.size();
int seconds_size = second.size();
if (firsts_size >= seconds_size){
int length = firsts_size;
}
else{
int length = seconds_size;
}
for (int i = length - 1; i >= 0; i--){
int digit_sum = first[i] + second[i] + carry;
if (digit_sum > 9){
carry = ((digit_sum / 10) % 10);
}
result.push_back(digit_sum);
}
return result;
}
So hey guys, you have all helped me out a couple of times and I am hoping that you can do the same thing again for me. So the purpose of this function in a C++ program is to take two vectors with digits, taken from large numbers, and to add them together and create a vector in the end with the sum to return from the function. However, I am having an issue with this, and I can't tell if it is a problem with the way I have done the actual addition or if some way I am printing them out in my main.
I have created another function to take a vector comprised of digits and turn it into a string to print back out as output, and I know this function works because it works a lot throughout my program. So I am convinced that something is going on with this function and causing me not to be able to print. However, Visual Studio does not throw any errors from it or anything, simply that where the output is supposed to be is left blank, which has left me stumped. Any help is greatly appreciated!! Just remember one thing, since this is the first program from my class I can't use anything too advanced to solve this issue. Thanks for the Help
I will assume you have the position i of the vector associated with the (i-1)-th power of 10.
EDITED: now it works also with different size vectors
vector<int> add_vectors(const vector<int> &first, const vector<int> &second){
vector<int> result;
int length = 0;
int carry = 0;
int firsts_size = first.size();
int seconds_size = second.size();
int digit_sum = 0;
if (firsts_size >= seconds_size){
length = firsts_size; // int here is not necessary
}
else{
length = seconds_size; // int here is not necessary
}
for (int i = 0, i<lenght; i++){
if (i>=lenght){
if (i>=firsts_size){
digit_sum = second[i] + carry;
}
else{
digit_sum = first[i] + carry;
}
}
else{
digit_sum = first[i] + second[i] + carry;
}
if (digit_sum > 9){
carry = 1; // carry will be no mor than 1 adding two numbers
digit_sum = digit_sum - 10;
}
else{
carry = 0;
}
result.push_back(digit_sum);
}
if (carry > 0){
result.push_back(carry);
}
return result;
}
I am trying to solve Project Euler Problem 88, and I did it without too much effort; however, I find that some seemingly irrelevant code in my program is affecting the result. Here's my complete code (it's not short, but I cannot locate the error. I believe it would be obvious to more experienced eyes, so please read my description first):
#include <iostream>
#include <set>
using namespace std;
bool m[24001][12001];
bool p[24001]; // <------------ deleting this line will cause error in result!
long long answer[12001];
int main() {
long long i;
long long j;
long long l;
set<long long> all;
long long s = 0;
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
m[i][j] = false;
}
}
m[1][1] = true;
for (i = 2; i <= 24000; i++) {
m[i][1] = true;
for (j = 2; (j <= i) && (i * j <=24000); j++) {
for (l = 1; l <= i; l++) {
if (m[i][l]) {
m[i * j][l + 1 + (i * j) - i - j] = true;
}
}
}
}
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
if (m[i][j] && (answer[j] == 0)) {
answer[j] = i;
}
}
}
for (i = 2; i <= 12000; i++) {
cout << answer[i] << endl;
all.insert(answer[i]);
}
cout << all.size() << endl;
for (set<long long>::iterator it = all.begin(); it != all.end(); it++) {
//cout << *it << endl;
s += *it;
}
cout << s << endl;
}
With the "useless" bool array, all the answers are right, between 0 and 24000; but without it, some answers in the middle got corrupted and become very large numbers.
I am completely confused now; why would that unused array affect the middle of the answer array?
Thanks and sorry for the long code! I will be grateful if someone could edit the code into a better example, I simply son't know what is with the code.
You do a silly thing in here:
m[i * j][l + 1 + (i * j) - i - j] = true;
Say, i=160, j=150, l=1... You will try to access m[24000][23692]... And you corrupt the stack, so behavior is undefined.
Next time try to use some profiler and/or debugger.
Add:
#include <cassert>
at the begining and
assert( (i * j) * 12001 + (l + 1 + (i * j) - i - j) <= 12001*24001 );
before the following line:
m[i * j][l + 1 + (i * j) - i - j] = true;
The assertion will fail, which means you write outside the bounds of the array m.
As requested, adding this to an answer.
You are definitely writing beyond the bounds of the array m somewhere, when the unused array p exists, m overwrites in to its contents which doesn't affect the answer array but once p is removed the overwriting happens in to answer array showing up the problems.
Overwriting beyond the bounds of the array is an Undefined Behavior and it causes your program to be ill-formed. With Undefined Behavior all safe bets are off and any behavior is possible. While your program may work sometimes or crash sometimes or give incorrect results.Practically, Anything is possible and the behavior may or even may not be explainable.
In one of your nested loops you use l as the index for the second dimension. This variable can run from 0 to i and i, in turn, can run from 0 to 24000. Since your second dimension of the array can only be index from 0 to 12000 this causes a classic out of range error. This also nicely explains why adding an extra array avoid the problem: the out of range accesses go to the "unused" array rather than overwriting the result.