This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Address space overflow and garbage values while using 'sprintf'

Dear all,
The linker gives following error:

*** ERROR L107: ADDRESS SPACE OVERFLOW
    SPACE:   DATA
    SEGMENT: ?DT?TIMER0_ISR?TIMER
    LENGTH:  0002H

I have a global buffer. If i declare it idata then the linker does not give any error. But the sprintf function gives garbage values.
I am unable to understand the problem.

The following is the piece of code:

dtptr = &buff;
strlen = sprintf(dtptr, "%d", PrbTemperature*1000);
UART_TxArray(dtptr, strlen);

PrbTemperature is a float. dtptr, buff[7] and strlen are unsigned char.

kindly assist.

  • strlen() is a function available in the C standard library - are you saying that you have added own variables with same name?

    Next thing - why do you have a float? You sure you really need a float to handle that temperature? Have you considered fixed point integers? That removes the need for linking in floating point support.

    Another thing - you do &buff. You realize that the name buff itself represents the address of the first element of the buff[] array.

    Have you verified that sprintf() gives your expected printout if you throw away some code/data so you don't have to change that buffer to idata? By the way - is it buff[] that you change to idata?

  • this is what i see on my terminal:

    Input Set-point Temperature
    20201
    ëGAÈ20264
    îGAï20298
    ðGB
    20309
    ïGB 20336
    ðGB20176
    óGB'19968
    òGB219977
    òGB>20239
    õGBN20425
    õGBT20433
    öGBZ20447
    õGBi20443
    õGBr20464
    ùGB€20443
    ùGBˆ20165
    úGB"20087
    ùGBŸ20260
    úGB«20542
    ûGB®20572
    ûGB¸20549
    üGB¿20565
    ûGBÅ20585
    üGBÌ20579
    ýGB×20342
    þGBä20220
    ÿGBê20275
    20597
    20702

    The numbers are correctly displayed except that they are prefixed with some garbage values which i am unaware of how they creep in.
    and this is the change made in the code:

    strlen = sprintf(dtptr, "%d", (uint16_t)(PrbTemperature*1000));
    

  • 1. strlen is a variable that i have declared in my function.
    2. I think float is required. or may be i can manipulate temperature by multiplying it with 1000 or 100. (other way round which i can think of, but dnt want to use. I am not confident about its working for all values of temperature)
    3. I wrote &buff just because i want the compiler to know that i am giving the address of an array and not a variable (foolishness)
    4. ya, i am defining buff as idata.

    regards,
    Dhaval

  • ya. the values returned from the sprintf in the buffer are correct (not garbage).

    strlen = sprintf(dtptr, "%d", (uint16_t)(PrbTemperature*1000));
    

    even after modifying to this, i get garbage the values as seen on terminal. the values are given in the next post

  • fixing it with IDATA only works if that leaves enough stack You, probably, have stack overflow

  • char buff[] = "1234567";
    char buff[7];
    char buff[] = {1, 2, 3, 4, 5, 6, 7};
    


    They all have in common that buff already is a const pointer to the buffer. You're passing a pointer to a pointer to sprintf, don't.

  • They all have in common that buff already is a const pointer to the buffer.

    Not really. buff "is" not a pointer --- it's an array. It just automatically turns into a pointer in most of its usages.

    You're passing a pointer to a pointer

    No, he isn't. He's passing a pointer to an array. Because appling the address-of operator '&' is actually one of the exceptions to the above "most of" rule.

    But you're still correct that &buff is not what should be passed to sprintf() --- even though it would usually work anyway. If you get a warning from your tools when you do this, you should consider that a good thing.

    The Right Way(no TM) to do this is one of

    sprintf(buff, ...);
    sprintf(&buff[0], ...);
    sprintf(&(buff[0]), ...);
    

    These are all exactly equivalent, so most experienced C programmers will use the first form simply because it's shorter. But you'll find the other two forms quite frequently, too.

  • I do the #2 when I want to be explicit. Else I use the #1.

    But I don't like type defines that are arrays - normally hide inside a struct to make the data a real black-box and avoid the array/pointer duality.