为什么在声明字符串时不需要分配内存

时间:2014-06-13 10:11:50

标签: c

我是C的新手,目前我正在努力了解指针是如何工作的。

这是一个令我困惑的问题:

据我所知,在为指针赋值之前,你应该为该指针分配一定的内存(如果我错了,请纠正我:)),如下面的代码:

int main(void) {
    int i;
    int * ptr = (int *)malloc(sizeof(int));

    i = 2;
    *ptr = 5;     
    printfn("%d",*ptr); 
    free(ptr);
}

但是,在C中声明字符串时,就像:

char *p = "Hello world"; 

无需分配内存。

原因是什么?它是如何运作的?如果我遗失了什么,请提醒我。

3 个答案:

答案 0 :(得分:8)

char *p = "Hello world";

你创建了一个指针并将其指向一个常量字符串。编译器将其放在标记为只读的内存中。

它没有名称,并且具有静态存储持续时间(意味着它在程序的整个生命周期中存在);以及一个名为p的指向char的类型的变量,它使用该未命名的只读数组中第一个字符的位置进行初始化。

答案 1 :(得分:4)

"Hello world"是静态数据,会被编译到您的二进制文件中,就像示例中的25一样。

char * p被定义为指向二进制文件中该位置的指针。

这也是 char const 的原因,因为您不应该到该位置。 (你的编译器应该给你一个警告。)

答案 2 :(得分:2)

  

...你应该为那个指针分配一些内存......

不,你似乎误解了指针...

指针是保存某些类型的地址的类型。看看这个例子。

int a = 1;
int *p = &a;

a的类型为int,其中包含整数

p的类型为int *,其中包含整数变量的地址

让我们假设这样的记忆:

--------------------------------------
variables: | a          | p          |
--------------------------------------
address  : | 0x12341234 | 0x12341238 |
--------------------------------------

&运算符获取操作数的地址。因此,&a等于0x12341234

所以变量初始化如下:

--------------------------------------
variables: | a          | p          |
--------------------------------------
address  : | 0x12341234 | 0x12341238 |
--------------------------------------
value    : | 1          | 0x12341234 |
--------------------------------------

现在,查看此代码*p*运算符解除引用运算符,获取指针所指向的变量的值。在这种情况下,p包含0x12341234 - 0x12341234中有哪些变量? a!因此*p等于1所包含的a


现在看一下这个例子:

#include <stdlib.h>

char c1 = '1';

int main()
{
    char c2 = '2';

    char *p1 = &c1;
    char *p2 = &c2;

    char ar[13] = "hello world!"; /* don't forget '\0' : 12 + 1. */

    char *p3 = &ar[0];
    const char *p4 = "hello world!"; /* notice the type, `const char *` */

    char *p5 = malloc(13 * sizeof(char));
}

c1是全局变量,因此编译器直接将它放在程序的数据部分上。 c2main的局部变量,因此main将其置于堆栈上。无论如何,他们被置于记忆中。 p1p2包含地址,因此*p1'1'c1),*p2为{ {1}}('2')。

c2ar的13长数组。它放在这样的记忆中:

char

------------------------------------------------------ |'h'|'e'|'l'|'l'|'o'|' '|'w'|'o'|'r'|'l'|'d'|'!'|'\0'| ------------------------------------------------------ &ar[0]的第一个元素的地址,因此ar包含p3的地址。

现在看看'h'。它由p4初始化。你的问题是它被分配的地方 - 它只是(字符串)常量,如"hello world!"12342.71。常量由编译器直接放在程序上。与'a'类似,字符串常量直接放在程序的 ro 数据部分上。与数据部分对比, rodata部分是只读的(只读数据),因为字符串常量是常量。 (如您所知,常量是只读的。)因此c1的类型为p4

const char *p5的返回值初始化,即来自动态分配。在这种情况下,malloc会在某处分配内存,malloc由此初始化。