gpt4 book ai didi

c - 返回指针的函数在第二次调用时使指针无效

转载 作者:太空宇宙 更新时间:2023-11-04 03:32:26 25 4
gpt4 key购买 nike

我正在调试/移植一些我发现有奇怪的不同行为的代码。我要确定的是(任何​​)编译器的正确行为。

当我有一个返回指针的函数,并且它被调用了两次,旧指针被新指针地址覆盖。 *byte_to_binary 函数演示了我制作的示例代码中的问题。如果我在 printf("%s\n",byte_to_binary(x)); 语句中使用单个 byte_to_binary 函数,我会得到以下结果:

00100000
11110000
11011000
11001100
11000110

如果我使用两个 byte_to_binary 调用作为参数,如

printf("%s %s\n",byte_to_binary(x),byte_to_binary(z));

你最终得到了代表 z 两次的指针,输出如下:

01100000 01100000
00110000 00110000
00011000 00011000
00001100 00001100
00000110 00000110

在很多方面,这对我来说很有意义,因为编译器似乎只是在重用地址,但从代码的角度来看,我会假设编译器只会在堆栈上抛出两个不同的结果。

我提供的这段代码是我从原始代码库中得出的最简洁、可重复的解释。原始代码是在 2006 年的某个时候使用 Sun 的 CC 为 Solaris 编译的(我无法再访问该机器),我现在使用的是 clang-700.1.81。原始代码导致了我预期的行为,即返回指向 x 然后 z 转换的指针。

#include <string.h> 
#include <stdio.h>
const char *byte_to_binary(unsigned char x)
{
static char bits[9];
bits[0] = '\0';
int z;
for (z=128;z>0;z>>= 1)
{ strcat(bits, ((x & z) == z) ? "1" : "0"); }
return bits;
}

int main (int argc, char **argv) {


unsigned char i;
unsigned char x=0x80;
unsigned char z=(3)<<5;
for(i=0;i<5;i++)
{
x=x-z;
printf("%s %s\n",byte_to_binary(x),byte_to_binary(z));
//printf("%s\n",byte_to_binary(x));
z = z >> 1;
}

}

最终的问题是,这条线是否应该

printf("%s %s\n",byte_to_binary(x),byte_to_binary(z));

return确实两次使用了byte_to_binary(z)的指针?

最佳答案

当您使用 byte_to_binary 的返回值作为 printf 的参数时,编译器“扔到堆栈上”的唯一结果是 指针 byte_to_binary 返回的值。您的 byte_to_binary 函数被特意实现为每次调用时返回相同 指针。它每次都返回指向相同内部静态缓冲区的指针。换句话说,对 byte_to_binary 的每次后续调用都会覆盖先前对 byte_to_binary 的调用的结果。

这立即意味着您通常不能在单个表达式中多次调用 byte_to_binary。您的 printf 将始终打印相同的字符串两次。哪个结果将“赢得”这场“比赛:- byte_to_binary(x)byte_to_binary(z) - 未指定。

即使您遵循在每个表达式中调用 byte_to_binary 的约定不超过一次,您仍然必须记住返回指针所指向的结果的生命周期只会延长到下一个调用 byte_to_binary

在这种情况下,返回指向单个内部静态缓冲区的指针并不是一种非常可行的技术。如果你真的渴望不必担心缓冲区管理的便利,至少使用静态缓冲区的循环集合。例如。像

const char *byte_to_binary(unsigned char x)
{
static char buffers[5][9];
static unsigned ibuffer = 0;

char *bits = buffers[ibuffer++];
ibuffer %= sizeof buffers / sizeof *buffers;

...

return bits;
}

这将在您的 printf 调用中产生预期的结果。它依赖于以循环方式使用的 5 个缓冲区。当然这种方法也有缺点,但在辅助代码中还是很可行的。

关于c - 返回指针的函数在第二次调用时使指针无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35300063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com