-
February 18th, 2016, 07:27 AM
#1
error : returning address of local variable or temporary
hi i found a code from internet i can't run this code getting errors need help am using visual studio 2013
This program is to handle all possible arithmetic operations (+, -, *, /, %) and logic operations (<, >, >=, <=, ==, !=) between 2 numbers
Code:
#include <iostream>
#include <string>
#define SIZE 120
using namespace std;
class bigInt {
public:
bigInt(char aBigInt[], bool negativeFlag = false, bool zeroFlag = false) { strcpy(a, aBigInt); setNegative(negativeFlag); setZero(zeroFlag); }
bigInt() { clear(a); setNegative(false); setZero(true); }
~bigInt() {};
bool getNegative(void) { return negative; }
bool getZero(void) { return zero; }
void setNegative(bool negativeFlag) { negative = negativeFlag; }
void setZero(bool zeroFlag) { zero = zeroFlag; }
const bigInt& operator=(const bigInt& rhs);
const bigInt& operator+(bigInt& b);
const bigInt& operator*(bigInt& b);
const bigInt& operator-(bigInt& b);
const bigInt& operator/(bigInt& b);
const bigInt& operator%(bigInt& b);
const void operator+=(bigInt& b);
const void operator*=(bigInt& b);
const void operator-=(bigInt& b);
const void operator/=(bigInt& b);
const void operator%=(bigInt& b);
const bool operator>(bigInt& b);
const bool operator<(bigInt& b);
const bool operator==(bigInt& b);
const bool operator!=(bigInt& b);
const bool operator>=(bigInt& b);
const bool operator<=(bigInt& b);
void getValue(char thisBigInt[]) {strcpy(thisBigInt, a); } // return a string which is equivalent to the number
void setValue(char thisBigInt[]) {strcpy(a, thisBigInt); } // set string thisBigInt to the value of an instance
int getLength() { return strlen(a); }
char getDigit(int pos) { return a[pos]; } // return CHARACTER at position i
void setDigit(int pos, char value) { a[pos] = value; } // set CHARACTER at position i to value
void print() { for (int i = 0; i < getLength(); i++) cout << a[i]; }
void reverse(void);
void clear(char ar[]) { ar[0] = '0'; ar[1] = '\0'; }
void fixArray(char ar[]);
private:
char a[SIZE];
bool negative;
bool zero;
//helper functions
int value(char c) { return c - 48; } //convert a character into the digit form
char represent(int k) { return (char)(k + 48); } //convert a digit into the character form
int maximum(int a, int b) { return (a > b) ? a : b; }
};
void bigInt::fixArray(char ar[])
{
int j = 0;
int len = strlen(ar);
while ((ar[j] == '0') && (j < len))
j++;
if (j == len)
clear(ar);
else {
for (int i = 0; i < len - j; i++)
ar[i] = ar[i + j];
ar[len - j] = '\0';
}
}
const bigInt& bigInt::operator=(const bigInt& rhs)
{
if (this != &rhs) { // check for self assignment
negative = rhs.negative;
zero = rhs.zero;
strcpy(a, rhs.a);
}
return *this; //enable cascading
}
//reverse a string
void bigInt::reverse(void)
{
int len = getLength();
for (int i = 0; i < len/2; i++) {
char temp = a[i];
a[i] = a[len-1-i];
a[len-1-i] = temp;
}
}
//========================================== Multiplication function ==============================//
const bigInt& bigInt::operator*(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
int i = 0, j = 0;
int carry[SIZE][SIZE];
int r[SIZE][SIZE];
//reverse 2 number for the convenience in computing
reverse();
b.reverse();
//initialize carry[][] and r[][]
for (i = 0; i <SIZE; i++)
for (j = 0; j < SIZE; j++) {
carry[i][j] = 0;
r[i][j] = 0;
}
//fill digits into the array r, which is the temp table in multiplying 2 numbers
for (i = 0; i < len2; i++) {
for (j = 0; j < len1; j++) {
int x = value(getDigit(j));
int y = value(b.getDigit(i));
if (j != 0) {
r[i][j+i] = (x * y + carry[i][j+i-1]) % 10; // each digit is computed from the product of 2 digits from the operands and the carry from the previous computation
carry[i][j+i] = (x * y + carry[i][j+i-1]) /10;
}
else {
r[i][j+i] = x * y % 10;
carry[i][j+i] = x * y / 10;
}
}
r[i][len1+i] = carry[i][len1+i-1];
}
int carry1[SIZE]; //carry array for the final product
int tempResult[SIZE]; //final product in digit form
//initialize carry1[] and tempResult[]
for (i = 0; i < SIZE; i++)
carry1[i] = 0;
for (i = 0; i < SIZE; i++)
tempResult[i] = 0;
//compute tempResult from the temp table
for (i = 0; i < len1 + len2; i++) {
for (j = 0; j < len2; j++)
tempResult[i] += r[j][i];
if (i == 0) {
carry1[i] = tempResult[i] / 10;
tempResult[i] = tempResult[i] % 10;
}
else {
int temp = tempResult[i];
tempResult[i] = (temp + carry1[i-1]) % 10;
carry1[i] = (temp + carry1[i-1]) / 10;
}
}
char result[SIZE];
//convert the final product in digit form into character form
for (i = 0; i < len1 + len2; i++)
result[i] = represent(tempResult[i]);
//check if there is a '0' at the beginning of the product
if (value(result[len1 + len2 - 1]) == 0)
result[len1 + len2 - 1] = '\0'; // if so, obmit it
else
result[len1 + len2] = '\0';
//reverse the operands to get back the original value
reverse();
b.reverse();
//reverse the final result in character form to obtain the correct order
bigInt returnResult(result);
returnResult.reverse();
return returnResult;
}
//=================================================================================================//
//========================================== Addition function ====================================//
const bigInt& bigInt::operator+(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
int i = 0;
//reverse 2 number for the convenience in computing
reverse();
b.reverse();
int numA[SIZE], numB[SIZE];
int carry[SIZE]; //carry array for the sum
int tempResult[SIZE]; //sum in digit form
//initialize numA[] and numB[]
for (i = 0; i < SIZE; i++) {
numA[i] = 0;
numB[i] = 0;
}
if (len1 > len2) {
for (i = 0; i < len1; i++)
numA[i] = value(getDigit(i));
for (i = 0; i < len2; i++)
numB[i] = value(b.getDigit(i));
for (i = len2; i < len1; i++)
numB[i] = 0;
}
else {
for (i = 0; i < len1; i++)
numA[i] = value(getDigit(i));
for (i = 0; i < len2; i++)
numB[i] = value(b.getDigit(i));
for (i = len1; i < len2; i++)
numA[i] = 0;
}
//initialize carry[] and tempResult[]
for (i = 0; i < SIZE; i++)
carry[i] = 0;
for (i = 0; i < SIZE; i++)
tempResult[i] = 0;
int len = maximum(len1, len2);
//compute tempResult
for (i = 0; i < len + 1; i++) {
tempResult[i] = numA[i] + numB[i];
if (i == 0) {
carry[i] = tempResult[i] / 10;
tempResult[i] = tempResult[i] % 10;
}
else {
int temp = tempResult[i];
tempResult[i] = (temp + carry[i-1]) % 10;
carry[i] = (temp + carry[i-1]) / 10;
}
}
tempResult[len+1] = carry[len];
char result[SIZE];
//convert the final product in digit form into character form
for (i = 0; i < len + 1; i++)
result[i] = represent(tempResult[i]);
//check if there is a '0' at the beginning of the product
if (value(result[len]) == 0)
result[len] = '\0'; // if so, obmit it
else
result[len + 1] = '\0';
reverse();
b.reverse();
//reverse the final result in character form to obtain the correct order
bigInt returnResult(result);
returnResult.reverse();
return returnResult;
}
//=================================================================================================//
//========================================== Subtraction function =================================//
const bigInt& bigInt::operator-(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
int i = 0, j;
bool negativeFlagOfResult = false;
bool zeroFlagOfResult = false;
int numA[SIZE], numB[SIZE];
int carry[SIZE]; //carry array for the sum
int tempResult[SIZE]; //sum in digit form
char result[SIZE];
//initialize result[]
for (i = 0; i < SIZE; i++)
result[i] = '0';
//initialize numA[] and numB[]
for (i = 0; i < SIZE; i++) {
numA[i] = 0;
numB[i] = 0;
}
if (*this > b) { //positive number
negativeFlagOfResult = false;
zeroFlagOfResult = false;
reverse();
b.reverse();
for (i = 0; i < len1; i++)
numA[i] = value(getDigit(i));
for (i = 0; i < len2; i++)
numB[i] = value(b.getDigit(i));
for (i = len2; i < len1; i++)
numB[i] = 0;
}
else if (*this < b) { //negative number
negativeFlagOfResult = true;
zeroFlagOfResult = false;
reverse();
b.reverse();
for (i = 0; i < len1; i++)
numB[i] = value(getDigit(i));
for (i = 0; i < len2; i++)
numA[i] = value(b.getDigit(i));
for (i = len1; i < len2; i++)
numB[i] = 0;
}
else {
negativeFlagOfResult = false;
zeroFlagOfResult = true;
clear(result);
bigInt returnResult(result, negativeFlagOfResult, zeroFlagOfResult);
returnResult.reverse();
return returnResult;
}
//initialize carry[] and tempResult[]
for (i = 0; i < SIZE; i++)
carry[i] = 0;
for (i = 0; i < SIZE; i++)
tempResult[i] = 0;
int len = maximum(len1, len2);
//compute tempResult
if (numA[0] < numB[0]) {
tempResult[0] = numA[0] + 10 - numB[0];
carry[0] = 1;
}
else {
tempResult[0] = numA[0] - numB[0];
carry[0] = 0;
}
for (i = 1; i < len; i++) {
if (numA[i] < carry[i-1] + numB[i]) {
tempResult[i] = numA[i] + 10 - carry[i-1] - numB[i];
carry[i] = 1;
}
else {
tempResult[i] = numA[i] - carry[i-1] - numB[i];
carry[i] = 0;
}
}
//convert the final product in digit form into character form
for (i = 0; i < len; i++)
result[i] = represent(tempResult[i]);
//remove unnecessary '0's at the beginning of the array
j = len - 1;
while ((result[j] == '0') && (j != -1))
j--;
if (j == -1)
clear(result);
else
result[j+1] = '\0';
reverse();
b.reverse();
//reverse the final result in character form to obtain the correct order
bigInt returnResult(result, negativeFlagOfResult, zeroFlagOfResult);
returnResult.reverse();
return returnResult;
}
//=================================================================================================//
const bigInt& bigInt::operator/(bigInt& b)
{
bigInt tempDividend, quotient;
char tempDividendResult[SIZE] = "", quotientResult[SIZE] = "";
char c;
int i = 0, j, k;
while (i < getLength()) {
if (tempDividend < b) {
c = getDigit(i);
tempDividend.getValue(tempDividendResult);
k = strlen(tempDividendResult);
tempDividendResult[k] = c;
tempDividendResult[k+1] = '\0';
tempDividend.fixArray(tempDividendResult);
tempDividend.setValue(tempDividendResult);
if (tempDividend < b) {
k = strlen(quotientResult);
quotientResult[k] = '0';
quotientResult[k+1] = '\0';
quotient.fixArray(quotientResult);
quotient.setValue(quotientResult);
i++;
}
}
else {
j = 0;
while (tempDividend >= b) {
tempDividend = tempDividend - b;
j++;
}
quotient.getValue(quotientResult);
k = strlen(quotientResult);
quotientResult[k] = represent(j);
quotientResult[k+1] = '\0';
quotient.fixArray(quotientResult);
quotient.setValue(quotientResult);
i++;
}
}
return quotient;
}
//=================================================================================================//
const bigInt& bigInt::operator%(bigInt& b)
{
bigInt tempDividend, quotient;
char tempDividendResult[SIZE] = "", quotientResult[SIZE] = "";
char c;
int i = 0, j, k;
while (i < getLength()) {
if (tempDividend < b) {
c = getDigit(i);
tempDividend.getValue(tempDividendResult);
k = strlen(tempDividendResult);
tempDividendResult[k] = c;
tempDividendResult[k+1] = '\0';
tempDividend.fixArray(tempDividendResult);
tempDividend.setValue(tempDividendResult);
if (tempDividend < b) {
k = strlen(quotientResult);
quotientResult[k] = '0';
quotientResult[k+1] = '\0';
quotient.fixArray(quotientResult);
quotient.setValue(quotientResult);
i++;
}
}
else {
j = 0;
while (tempDividend >= b) {
tempDividend = tempDividend - b;
j++;
}
quotient.getValue(quotientResult);
k = strlen(quotientResult);
quotientResult[k] = represent(j);
quotientResult[k+1] = '\0';
quotient.fixArray(quotientResult);
quotient.setValue(quotientResult);
i++;
}
}
return tempDividend;
}
//=================================================================================================//
const void bigInt::operator+=(bigInt& b)
{
bigInt result;
result = *this + b;
*this = result;
}
const void bigInt::operator*=(bigInt& b)
{
bigInt result;
result = *this * b;
*this = result;
}
const void bigInt::operator-=(bigInt& b)
{
bigInt result;
result = *this - b;
*this = result;
}
const void bigInt::operator/=(bigInt& b)
{
bigInt result;
result = *this / b;
*this = result;
}
const void bigInt::operator%=(bigInt& b)
{
bigInt result;
result = *this % b;
*this = result;
}
const bool bigInt::operator>(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
if ((!negative) && b.getNegative())
return true;
else if (negative && (!b.getNegative()))
return false;
else if ((!negative) && (!b.getNegative())) {
if (len1 > len2)
return true;
else if (len1 < len2)
return false;
else {
int j = 0;
while ((a[j] == b.a[j]) && (j != len1))
j++;
if (j == len1)
return false; // a == b
else {
if (value(getDigit(j)) > value(b.getDigit(j)))
return true;
else
return false;
}
}
}
else if (negative && b.getNegative()) {
if (len1 > len2)
return false;
else if (len1 < len2)
return true;
else {
int j = 0;
while ((a[j] == b.a[j]) && (j != len1))
j++;
if (j == len1)
return false; // a == b
else {
if (value(getDigit(j)) > value(b.getDigit(j)))
return false;
else
return true;
}
}
}
}
const bool bigInt::operator<(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
if ((!negative) && b.getNegative())
return false;
else if (negative && (!b.getNegative()))
return true;
else if ((!negative) && (!b.getNegative())) {
if (len1 > len2)
return false;
else if (len1 < len2)
return true;
else {
int j = 0;
while ((a[j] == b.a[j]) && (j != len1))
j++;
if (j == len1)
return false; // a == b
else {
if (value(getDigit(j)) > value(b.getDigit(j)))
return false;
else
return true;
}
}
}
else if (negative && b.getNegative()) {
if (len1 > len2)
return true;
else if (len1 < len2)
return false;
else {
int j = 0;
while ((a[j] == b.a[j]) && (j != len1))
j++;
if (j == len1)
return false; // a == b
else {
if (value(getDigit(j)) > value(b.getDigit(j)))
return true;
else
return false;
}
}
}
}
const bool bigInt::operator==(bigInt& b)
{
int len1 = getLength(), len2 = b.getLength();
if (len1 != len2)
return false;
else {
int j = 0;
while ((a[j] == b.a[j]) && (j != len1))
j++;
if (j == len1)
return ((negative && b.getNegative()) || (!negative && (!b.getNegative()))); // a == b
else
return false;
}
}
const bool bigInt::operator!=(bigInt& b)
{
return !(*this == b);
}
const bool bigInt::operator>=(bigInt& b)
{
return ((*this > b) || (*this == b));
}
const bool bigInt::operator<=(bigInt& b)
{
return ((*this < b) || (*this == b));
}
//========================================== MAIN FUNCTION ========================================//
void main(void)
{
bigInt a("123");
bigInt b("45");
bigInt c;
c = a % b;
c.print();
cout << endl;
/**/
}
-
February 18th, 2016, 08:24 AM
#2
Re: error : returning address of local variable or temporary
To get rid of the error, just use the strcpy_s function instead of strcpy.
https://msdn.microsoft.com/en-us/library/td1esda9.aspx
You also get warnings because the code returns references to local variables. The variables will be destroyed, so it's dangerous.
For example:
Code:
const bigInt& bigInt::operator-(bigInt& b)
Normally one would expect:
Code:
bigInt bigInt::operator-(const bigInt& b)
Last edited by TubularX; February 18th, 2016 at 08:38 AM.
-
February 18th, 2016, 08:43 AM
#3
Re: error : returning address of local variable or temporary
Code:
const bigInt& bigInt::operator*(bigInt& b)
{
// ...
bigInt returnResult(result);
returnResult.reverse();
return returnResult;
}
The warning is pretty explicit. It is returning a reference to a temporary value. It's wrong. These binary operators should return by value.
Only mutating binary operations (eg +=, *=, etc) should return a reference (to self). Ironically enough, here, it returns void.
Originally Posted by Ramees219
hi i found a code from internet i can't run this code getting errors need help
Maybe you can fix it, but I wouldn't put too much faith in it. I suggest finding a better library.
The "de facto" big num library is GMP, but it is somewhat difficult to install, and to use. I'd recommend it if you now exactly what you are doing, and where you want to go.
On the other hand TTMath seems like a reputable library that strikes good balance between ease of use and quality. It's header only, so should be easy to "install" (IE, just put it in your includes and done).
http://www.ttmath.org/
I'd recommend trying that.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
February 18th, 2016, 09:10 AM
#4
Re: error : returning address of local variable or temporary
Code:
const bigInt& bigInt::operator*(bigInt& b)
...
bigInt returnResult(result);
returnResult.reverse();
return returnResult;
That is a big no-no as you are returning by reference to a variable which doesn't exist once the function exits - so the returned reference is invalid. Variables local to the function need to be returned by value. This will invoke the copy constructor unless an appropriate ref-ref move constructor has been implemented.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
February 18th, 2016, 09:44 AM
#5
Re: error : returning address of local variable or temporary
On the other hand TTMath seems like a reputable library that strikes good balance between ease of use and quality. It's header only, so should be easy to "install" (IE, just put it in your includes and done).
http://www.ttmath.org/
I'd recommend trying that.
now i am trying to install flint library but its really tough for me Oky finally i think I found nice library that i can use easily thanks
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|