关于char指针的一些问题

时间:2010-06-02 19:16:50

标签: c pointers char

1-这是如何工作的:

char *ptr = "hi";

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

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

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

4 个答案:

答案 0 :(得分:6)

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)或更新后的值(b)?编译器可以但不一定共享这样的静态字符串;有些人还将整个区域标记为只读,因此尝试写入该区域将产生异常。

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

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

  2. 将释放指针的内存。

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

答案 3 :(得分:1)

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

    const char *ptr = "hi";

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

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

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

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