【问题标题】:Weird output behavior with char array in C [duplicate]C中char数组的奇怪输出行为[重复]
【发布时间】:2020-06-07 15:14:23
【问题描述】:

我有一个函数,当我在它打印的主页面上使用 printf("%c", *(k+i)); 打印它时返回 char*;

0' 10101001 Q -> Q

但如果我使用printf(" %c", *(k+i)); 打印,问题就会减少。 如果我在 tobinary 函数中打印,输出会像这样完美;

1010.011010011011101001011110001101010011111101111100111 -> 111011

我做错了什么?这是代码。

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(" -> ");
    }
}

【问题讨论】:

    标签: c arrays pointers char


    【解决方案1】:

    当你在函数中声明一个局部变量时,像这样

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

    它存储在称为 stack 的特殊内存区域中。每当调用函数func()时,CPU都会在那里保存一些有用的数据,例如调用函数的地址,在func()返回后将恢复执行,以及func()的参数,正如我上面写的, 在其中声明的任何局部变量。

    所有这些数据都以 LIFO 标准(后进先出)堆叠,因此当函数返回时,特殊指针(堆栈指针)会更改为指向与调用有关的数据功能。 func()的数据仍然存在,但只要调用另一个函数或caller()声明了其他局部变量,它就可以被覆盖。请注意,它符合局部变量的事实生命周期仅限于声明它们的函数。


    这就是您的场景中发生的情况。由于执行继续,您的 bin[] 数组不能保证保持“安全”:

    • int i 在 for 循环部分中声明
    • printf() 被调用

    这就是破坏“你的”数据的原因(我使用了双引号,因为它不再是你的了)。


    当您需要返回由函数操作的数据时,您有以下三种选择:

    1. 在其外部声明数组并在更改其原型后将其传递给函数:int tobinary(char *arr, unsigned int arrsize, double num);。通过这种方式,函数可以修改调用者传递的数据(最多更改arrsize 个字符)。返回值可以变成错误码; 0 表示成功,-1 表示失败。
    2. 使用malloc() 在函数内部动态分配数组。在这种情况下,释放内存(使用free())是调用函数的责任。
    3. 将函数中的数组声明为static。这个限定符,其实就是告诉编译器,变量的lifetime就是程序的整个生命周期,用不同的特定内存区域来存储它,而不是堆栈。请注意,在这种情况下,您的函数将不再是线程安全的(访问同一内存区域的不同线程会导致奇怪的结果)。

    【讨论】:

    • 非常感谢!分配数组解决了我的问题,你的整个答案都非常有用
    【解决方案2】:

    bin 是函数内部的字符数组。

    它不是静态的,所以当你返回一个指向它的指针时,它不能保证保持相同的值。

    要么将其更改为static,要么返回您分配的内存,调用者将需要释放该内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多