Prev: Simple C question from a newbie. - Getting ascii value of akeypress.
Next: Any LED backlit external monitirs for laptop use?
From: Robert Billing on 16 May 2010 06:36 I'm a long-tern C programmer who is trying to convert to C++, and as a first project I have written a class that implements "infinite precision" integer arithmetic. This hold integers in the following form: int sign ; /* True if <0 */ int space ; /* Allocated bytes */ int used ; /* Bytes actually used */ unsigned char *val ; /* The value, held lsb first */ The val member is created with an invocation of new, and released by a destructor. I have implemented the operators =, +, -, *, /, %, <<, >>, &, |, ^, +=, - =, *=, /=, %= <<=, >>=, &=, |=, ^= and the stream write <<. I also have monadic +, - and ~. The bitwise operators are implemented on the assumption that a negative integer is used in twos-compliment format with the sign extended as required. There are also conversions to and from both integer and string. The value is held little-endian magnitude with a separate sign, and can be of any size consistent with the local addressing length. Most of this has worked with little trouble, in fact the last few operators worked at the first attempt. However I did run into one problem for which I found a workaround that I think is rather messy. I'd like to know if there is a cleaner solution. This is the relevant code, which converts an infinite int to a class string at any base and with arbitrary options. The accumulator acc is set to the absolute value of the number to be converted, and divisor to the base. Repeated divisions are then used to generate the digits one at a time. As the program stands - the working version is below - acc is set up by a default constructor which sets zero, and then assigned from the number to convert. I have overloaded the assignment operator with a procedure that copies sign, allocates new memory for val and fills in space and used. /* Generic conversion to text. Number is left padded to width, converted using base which can be 2 to 16. Flags define the options, see header. */ string infinite_int::text ( int width, int base, int flags ) const { string res, txt_sign ; infinite_int acc, divisor = base, quot, rem ; int digit, fill ; /* Convert the unsigned value */ acc = *this ; acc . sign = 0 ; THE PROBLEM is that if I don't do an explicit alignment, but write infinite_int acc = *this ; in the definitions it doesn't invoke my overloaded = operator, but simply clones the input instance. This leaves two instances with the same value of val, pointing at the same memory. When one of these is destroyed the memory is freed, but the other continues to point to it. This can cause a later crash. Is there a way that I can make my overloaded = operator work when defining a variable which is a class? Should I be providing an additional constructor?
From: Paul Bibbings on 16 May 2010 07:38 Robert Billing <unclebob(a)tnglwood.demon.co.uk> writes: > THE PROBLEM is that if I don't do an explicit alignment, but write > > infinite_int acc = *this ; Despite the superficial similarity of syntax the above effects initialization, *not* assignment. your overloaded assignment operator is, therefore, naturally not considered here. In effect you are invoking the class' copy constructor, but even here there can be complications in some clearly-defined instances owing to the fact that the implementation is permitted to elide this even if the copy-ctor has side effects. You haven't said whether or not you have overloaded your copy constructor, but you might want to do this to obtain the semantics that you require, and then you might want to consider invoking it explictly using: infinite_int acc(*this); in place of the above. > in the definitions it doesn't invoke my overloaded = operator, but simply > clones the input instance. This leaves two instances with the same value > of val, pointing at the same memory. When one of these is destroyed the > memory is freed, but the other continues to point to it. This can cause a > later crash. > > Is there a way that I can make my overloaded = operator work when defining > a variable which is a class? Should I be providing an additional > constructor? Regards Paul Bibbings
From: Robert Billing on 16 May 2010 08:26
We, the Senate of Arcturus, take note that Paul Bibbings said: > Robert Billing <unclebob(a)tnglwood.demon.co.uk> writes: >> THE PROBLEM is that if I don't do an explicit alignment, but write >> >> infinite_int acc = *this ; > > Despite the superficial similarity of syntax the above effects > initialization, *not* assignment. your overloaded assignment operator > is, therefore, naturally not considered here. > > In effect you are invoking the class' copy constructor, but even here > there can be complications in some clearly-defined instances owing to > the fact that the implementation is permitted to elide this even if the > copy-ctor has side effects. Ah, thanks! The penny suddenly drops with a deafening clang. I now see what's going on. |