Weird output behavior with char array in C [duplicate]

£可爱£侵袭症+ 提交于 2020-07-10 07:46:46

问题


I have a function that returns char* when I print it with printf("%c", *(k+i)); on the main it prints;

0' 10101001 Q -> Q

but if I print with printf(" %c", *(k+i)); there are less problem. If I print inside the tobinary function, output comes perfect like this;

1010.011010011011101001011110001101010011111101111100111 -> 111011

What Am I doing wrong? here is the code.

char *tobinary(double num) {
    int length = 62;
    char bin[length];
    int intpart = (int)num;
    double decpart = 1000*(num - intpart);

    int i = 0;
    while (intpart!=0) {
        if(intpart%2 == 1) bin[3-i] = '1';
        else bin[3-i] = '0';
        intpart /= 2;
        i++;
    }

    bin[i++] = '.';
    while (i <= length) {
        decpart *= 2;
        if (decpart >= 1000) {
            bin[i] = '1';
            decpart -= 1000;
        }
        else bin[i] = '0';
        i++;
    }
    char *k = bin;
    return k;

}


int main(int argc, char **argv) {
    char *k = tobinary(10.413);
    for(int i = 0; i <= 62; ++i) {
        printf("%c", *(k+i));
        if (i==56) printf(" -> ");
    }
}

回答1:


When you declare a local variable in a function, like this

char *tobinary(double num) {
    int length = 62;
    char bin[length];

    /* ... */
}

it is stored in a special memory area called stack. Whenever a function func() is called, the CPU saves there some useful data such as the address of the calling function where the execution will be restored after func() returns, along with the parameters of func() and, as I wrote above, any local variable declared in it.

All this data is stacked with a LIFO criteria (Last In, First Out), so that when function returns a special pointer (stack pointer) is changed to point back to the data regarding the calling function. func()'s data is still there, but it can be overwritten whenever another function is called or other local variables are declared by caller(). Please note that it is compliant with the fact that local variables have a lifetime limited to the function in which they are declared.


That's what happen in your scenario. Since the execution goes on, your bin[] array is not guaranted to stay "safe":

  • int i is declared in the for-loop section
  • printf() is called

This is what corrupts "your" data (I used double quotes because it is not yours anymore).


Whenever you need to return data manipulated by a function, you have three options:

  1. Declare the array outside it and pass it to the function after changing its prototype: int tobinary(char *arr, unsigned int arrsize, double num);. In this way the function can modify the data passed by the caller (changing at most arrsize characters). The return value can become an error code; something like 0 on success and -1 on failure.
  2. Dynamically allocate the array inside your function using malloc(). In this case freeing the memory (with free()) is responsability of the caller function.
  3. Declare the array in your function as static. This qualifier, in fact, tells the compiler that the lifetime of the variable is the whole life of the program, and a different specific memory area is used to store it instead of the stack. Be aware that in this case your function won't be thread safe anymore (different thread accessing the same memory area would lead to bizarre results).



回答2:


bin is character array inside your function.

It is not static, so when you return a pointer to it, it is not guaranteed to keep the same value.

Either change it to static or return a memory you allocate and the caller will need to free that memory.



来源:https://stackoverflow.com/questions/62247424/weird-output-behavior-with-char-array-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!