This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Bizarre Stack Overflow on itoa

Hi,

I have been using the same itoa function for quite some time now (on the (msp2619)with no problems what so ever. It worked perfectly fine yesterday as a matter of fact...

This may be unrelated, but I updated my CCSv5 and installed some of the emulator updates... (Coincidence?)

Anyway, whenever I call the itoa function the msp resets. I am not sure if it is actually a stack over flow to be honest. 

The issue seems to be at the RETA call

0040cc: 09CC MOVA R9,R12
0040ce: 0E4C RLAM.A #4,R12
0040d0: 0D4C RRAM.A #4,R12
0040d2: 08EC ADDA R8,R12
70 }
0040d4: 1637 POPM.A #4,R10
0040d6: 0110 RETA

When I hit that I get taken to no where and eventually I reset. 

Here is the itoa in question:

// returns pointer to ASCII string in a char[] buffer
char* itoa(int value,char buffer[])
{
//char buffer[bufferSize]; // 12 bytes is big enough for an INT32
int original = value; // save original value

int c = sizeof(buffer)-1;

buffer[c] = 0; // write trailing null in last byte of buffer

if (value < 0) // if it's negative, note that and take the absolute value
value = -value;

do // write least significant digit of value that's left
{
buffer[--c] = (value % 10) + '0';
value /= 10;
} while (value);

if (original < 0)
buffer[--c] = '-';

return &buffer[c];
}

What do you guys think?

  • So I just went into a project that had that exact itoa function used in it and called it at the beginning of main (after HW init)

    and found that it did reset!

    Out of curiosity I went and called one of the functions that made use of this function and it worked fine. 

    Now the itoa works fine in that file, but still does not work in the new project. 

    This is frustrating...

  • I think you might have problem with this line

    int c = sizeof(buffer)-1;

    Technically buffer is a pointer that can be 2 to 4 bytes depending on the compiler options. So the variable 'c' will get initialized to 1 or 3. If the value passed in is more than 1 or 3 digits, the itoa() code will write into memory preceding the buffer array. You might overwrite a return address if buffer is allocated near the return address. A quick work-around would be to pass in the actual size of the buffer and use that instead of sizeof().

  • Norman is right. It is not "Bizarre Stack Overflow on itoa". It is your code that is bizarre!.

    In c, when you pass an array to a subroutine, you only pass a pointer. Thus the subroutine only knows the size of the pointer. You are mistaken that as the size of the array.

  • I was under the assumption that in C when you put an array as a parameter it automatically passes the pointer to the array?

    This is why I can pass the function something like this: &buffer[0]

    What seems to be happening is if I place the char buffer[] in a local function and call itoa then it crashes.

    I am pretty sure that you are correct about the sizeof() function. Its troubling that I missed that.

    Did I change something on the MSP compiler settings?

    Also: since we are on the subject: do you guys know any faster alogorithms for itoa? I would like to get rid of the modulus/division...

  • If the buffer was declared locally, the sizeof() operator would have worked properly. C does pass a pointer to the beginning of the array. It does not pass the size of the array. Your code would work with the commented out buffer is declared as a global variable or as a static local variable.

    /* Not reentrant or thread safe. */
    static char buffer[7]; // -32768 to 32767, 6 chars+1 terminator
    const char *itoa(int value)
    {
      int original = value; // save original value
      int c = sizeof(buffer)-1;
      ...
    }

    The itoa() problem has been discussed at some length on this forum. My code is posted here:

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/187230/677346.aspx#677346

    It uses a repeated subtraction algorithm proposed by Jens-Michael Gross.

  • Thanks Norman, 

    Your code is awsome. 

    I should probably look over some of the library functions that I wrote some time ago...

    Thanks Everyone!

    Derek 

  • Derek Belle said:
    I was under the assumption that in C when you put an array as a parameter it automatically passes the pointer to the array?

    Yes, but non-static local variables are placed on the stack, so right above the buffer space is the return address. if youo write beyond the buffer array limit, you overwrite teh data following it on the stack, which is the return addressfrom the ITOA function. on RETA, the CPU then returns to the value that was written by ITOA instead to the correct return address.

    If you declared buffer as global variable, it may seem to work. But actually you'll also overwrite some other global data or unused memory space - just not the return address and therefore no crash.

**Attention** This is a public forum