繁体   English   中英

关于char指针的一些问题

[英]A few questions about char pointers

1-这是如何工作的:

char *ptr = "hi";

现在编译器会把这个字符串放在内存中(我在猜测堆栈),并创建一个指向它的指针? 这是它的工作原理吗?

2-如果它是在函数中本地创建的,当函数返回时,字符串占用的内存是否会被释放?

3-最后但并非最不重要的,为什么不允许这样做: ptr[0] = 'H';

1)字符串 (通常)在堆栈上 - 它通常位于直接从可执行文件中读取的初始化数据段中。 然后将指针初始化为该字符串的地址。

2)不。

3)因为标准说它给出了未定义的行为。 考虑一下你是否有这样的事情:

int a() { char *a = "a"; printf("%s\n", a); }
int b() { char *b = "a"; *b = 'b'; }

int main() { 
    b();
    a();
    return 0;
}

现在,当你打印出a ,你希望得到的原始值(A)或更新的价值(二)? 编译器可以但不一定共享这样的静态字符串; 有些人还将整个区域标记为只读,因此尝试写入它将产生异常。

从C标准的角度来看,唯一合理的答案是将其称为未定义的行为。

  1. 编译器会将字符串“hi”放在内存中的某个位置(它不是标准所在的位置),而且你不知道在哪里,但你必须考虑到它可能放在一个只读的部分内存(虽然是编译器来决定)。 然后将创建一个指针指向内存中此位置的开头。

  2. 内存不一定会被释放,因为在大多数情况下,这个字符串将驻留在内存的数据部分(与编译指令相同的位置)。

  3. 这是不允许的,因为标准不保证对这种自动分配的内存块的写访问(参见1.)。 它可能适用于某些系统/平台/编译器,但标准不保证。

  1. 编译器将指针指向内存中的字符串,并将字符串“hi”的地址放在指针中。 字符串本身将位于程序的代码映像中。

  2. 指针的内存将被释放。

  3. 因为代码定义的ptr指向代码图像中的常量。 你不能写一个常数。

  1. 您可以更准确,更健壮地将其表达为:

    const char *ptr = "hi";

    然后不仅在您的代码中表达了actualité,而且编译器还会捕获尝试写入ptr指向的内存。 字符串本身是一个'静态常量'(因此不在堆栈上),指针是一个初始化为字符串地址的变量。

  2. 不,只有cyinter将在堆栈上实例化。 数据将保留在静态常量存储器中(通常作为代码文本段的一部分)。 大多数编译器/链接器工具链将匹配常见字符串,因此,例如,如果您的代码中有多个“hi”实例,则它们实际上都将引用相同的单个实例。

  3. 这是未定义的行为。 根据文本的存储方式,它可能有效,也可能无效。 现代处理器/ OS经常实现保护机制,以保护代码段免受修改和执行; 因为这些字符串通常也在代码段中,尝试修改字符串可能会导致运行时异常。 通过声明指针const在编译时检测此错误要好得多。

    如果您碰巧使用的是16位DOS编译器或没有内存保护的目标,它可能会起作用; 但是因为我可以整理常用字符串,所以您可能正在修改由多个指针引用的字符串。 在嵌入式目标上,字符串可能驻留在ROM中,在这种情况下,即使访问不被捕获为非法,也不会产生任何影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM