c - 一次又一次初始化时,指针在循环内做了什么?

标签 c loops pointers gcc char

我正在使用 GNU ARM 嵌入式工具链处理 STM32 uC。我试图找出在循环内初始化指针时会发生什么。一个非常小的例子如下(部分伪代码):

while(1)
{
    char* msg = "my message";
    transmit_via_uart(msg, strlen(msg));
    delay(1000);
}

每次再次初始化指针msg时,处理器是否为堆上的字符串分配新的空间?或者它是否会覆盖“旧”指针 msg 指向的空间(未分配新空间)?

我知道,我可以将初始化行放在 while 循环之上,我只是好奇会发生什么,无法弄清楚。

感谢您的快速回答!

编辑:抱歉!当然,编译器不会分配任何东西……:)

最佳答案

C 程序永远不会在堆上分配,除非您显式使用 malloc 系列函数。

字符串文字 "my message" 存储在 ROM 中(可能在大多数系统上称为 .rodata.text 的部分) .它在程序启动时分配在那里。

msg 指针仅仅指向 ROM 中的那个地址。指针本身分配在堆栈或 CPU 寄存器中。

然而,编译器足够聪明,可以看到即使您在循环中重复调用它,地址也不会改变。因此,它很可能会优化变量 msg,并简单地将可以找到字符串的原始硬编码 ROM 地址传递给函数。

您可以将初始化放在循环之上就好了,除非您使用的是石器时代的 30 年前的 C90 编译器。


作为旁注,编写代码的更好方法是:

char msg[] = "my message";
transmit_via_uart(msg, sizeof(msg)-1);

通过这种方式,您可以在编译时计算字符串文字的大小,因为它是常数且已知。通过使用 strlen,您可以强制进行运行时计算,而编译器可能不够智能,无法进行优化。

关于c - 一次又一次初始化时,指针在循环内做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55684932/

相关文章:

在c中将字符组转换为字符串

c - 如何使用 Fake Function Framework (FFF) 伪造一个采用 2D 数组作为输入的 C 函数?

c++ - 二维数组的 Big-O 插入

SQL:循环单选与带 IN 子句的单选

c - 从 STDIN 读取一行以仅使用 C 提取数字标记

c++ - 如何在嵌入式系统上创建指向寄存器的 constexpr 指针

c - 降序堆排序

java - 想要循环但变量未初始化

c - 在 C 中,我无法获取成员结构(双指针)的指向值。值在赋值函数外丢失

c - C中的指针运算