Dynamic Char Array for class constructor

Nov 14, 2013 at 10:48pm
I'm writing a class that has two constructors. However, I can't get them to work quite right.
One constructor has a parameter of an int (with a default value of 0) and the other has a parameter of a C-style string.

First of all, are these function prototypes correct for the constructors?
1
2
MyInt(int n = 0);	// first constructor, int param, default value 0
MyInt(const char * c);	// second constructor, c-style string param 



Both constructors work fine in some cases but don't work in all cases.

Here are some potential calls to these functions that are supposed to work:

1
2
3
4
5
6
7
8
9
10
// These two work fine
MyInt x(12345),
y("9876543210123456789"),
// The array assignment doesn't work when the value is negative
// I'm not allowing negative numbers, but I want to create the object and assign the array to 0
r1(-1000),
// This is incorrect input, since it is not an actual number, should also be set to 0. Doesn't work
r2 = "14H67",
// This should act as if I called the first (int) constructor and default to the value of 0? Doesn't work
r3;



This is the first constructor function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
MyInt::MyInt (const char * c)
{
   bool error = false;
   for (int i = 0; i < static_cast<int>(strlen(c)); i++)
      if (!isdigit(c[i]))
          error = true;

   if (error)
   {
      currentSize = 2;
      maxSize = currentSize + 5;
      digits = new char[maxSize];
	  digits[0] = '0';
	  digits[1] = '\0';
   }
   else
   {
      currentSize = static_cast<int>(strlen (c));
      maxSize = currentSize + 5;
      digits = new char[maxSize];

      int count = currentSize;
      for (int i = 0; i < currentSize; i++)
      {
         digits[count] = c[i];
         count--;
      }
   }
}



And here's the second:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
MyInt::MyInt (int n)
{
   int tempDigits = 0;
   char * temp;
   if (n < 0)
   {
      tempDigits = 2;
	  temp[0] = '0';
	  temp[1] = '\0';
   }
   // This part just tries to convert the int into a char array.
   // And this part seems to work fine, actually.
   else
   {   
      // Holder to compare value of int to maximum possible value
      // which has 10 digits
      int placeCheck = 1000000000;

      // Determine number of digits
      for (int i = 0; i < 9; i++)
        if ((n / placeCheck) > 0)
         {
            tempDigits = 10 - i;
            break;
         }
         else
            placeCheck /= 10;

      temp = new char[tempDigits];

      int thisDigit;

      // Put digits into a char array
      for (int i = 0; i < tempDigits; i++)
      {
         if (placeCheck == 10)
            thisDigit = (n / placeCheck);
         else if (placeCheck == 1)
            thisDigit = n;
         else
            thisDigit = (n / placeCheck) % (placeCheck / 10);
         temp[i] = I2C(thisDigit);
         n = n - (thisDigit * placeCheck);
         placeCheck /= 10;
      }
  }
         
   // initialize object data
   currentSize = tempDigits;
   maxSize = currentSize + 5;
   digits = new char[maxSize];

   int count = currentSize;
   for (int i = 0; i < currentSize; i++)
   {
      digits[count] = temp[i];
      count--;
   }
   delete [] temp;
}





Here's the private data from the class (from the header file):

1
2
3
4
5
6
7
private:
   int currentSize,
        maxSize;
   char* digits;			// Pointer to an array of digits

   // Increase the size of digits array by 5
   void Grow ();




And... I have other problems with this program but I think if I can figure out this, it'll be a big help!
Last edited on Nov 14, 2013 at 10:52pm
Nov 14, 2013 at 10:55pm
// Does not work when value is negative... it's supposed to assign a value of 0 to the array, since we're not allowing negative numbers.
r1(-1000),


For this.. the problem is here:

1
2
3
4
5
6
7
8
9
10
MyInt::MyInt (int n)
{
   int tempDigits = 0;
   char * temp; // you do not allocate any space for temp
   if (n < 0)
   {
      tempDigits = 2;
	  temp[0] = '0'; // so this is writing to a BAD POINTER  (<explode>)
	  temp[1] = '\0';
   }



// This is an incorrect input, since it is not an actual number, should also be set to 0, but it's not.
r2 = "14H67",


Yes, I agree it should be doing that. I don't see why it wouldn't. What output are you getting?

// This should act as if I called the first (int) constructor and default to the value of 0?
r3;



Yes.




As a side note... any particular reason you're doing the manual memory management (difficult, error prone) instead of just using std::string?
Nov 14, 2013 at 11:10pm
It's for an assignment. The purpose is to create a class that acts a new integer-type of thing. So, our objects should theoretically be able to hold an number of "any" size.
It stores the number as an array of digits (which I chose to use chars for... might be easier to make it an integer array, but it I still need to figure out the c-string constructor at least).

Oh, yeah. I need to give temp some space, shouldn't I?
I think I had something like this at some point, but couldn't get it to work either:
1
2
3
4
5
char * temp;
tempDigits = 2;
temp = new char[tempDigits];
temp[0] = '0';
temp[1] = '\0';



I have another function I wrote that's an operator overload of the extraction operator (operator<<) that's supposed to allow me to print my arrays. It just doesn't print anything for the ones that don't seem to be working. But it works fine for some.

I tried to run a debugger in Visual Studio but couldn't figure out the actual values that were being put into the arrays for the objects that won't print right, so I'm not sure where the problem is exactly. I've been assuming it's a problem with the assignment of values into the array during the objects' construction.
Topic archived. No new replies allowed.