这个问题听起来可能很愚蠢,但我不太确定。我是说,有什么区别:
char* line = (char*) malloc(MAX_LINE_LEN);
和
char line[MAX_LINE_LEN];
确切地?我知道前者是一个指针,后者是一个数组,但系统如何区分两者呢?内存是如何分配/存储的?
另外,当
line
被声明为指针而不是数组时,为什么可以删除它占用的内存?我认为数组存储在其他地方,当它超出作用域时,系统会自动释放它的内存,这在处理指针时不会发生,所以必须自己删除它。我错了吗?
最佳答案
char* line = (char*) malloc(MAX_LINE_LEN);
这是一个糟糕的风格;您不需要在C中强制转换
malloc
。让我们将其分成两部分,因为这样更容易描述和比较:char *line;
声明一个指向名为line
的字符的指针。可以将其指定为指向对象(或不指定任何对象)。对象的大小是其类型的大小,因此sizeof
是sizeof (line)
,这因系统而异。sizeof (char *)
是&line
的地址,其类型为char *
(指向指向char的指针)。它的存储时间取决于声明的位置:如果它是在任何函数之外声明的,则它具有静态存储持续时间,该持续时间为程序的生存期。具有静态存储持续时间的对象初始化为
char **
,除非存在显式初始化(例如在您的情况下)。0
是一个0
,表示如果在没有初始化器的函数外部声明此对象,则它将不指向任何内容。如果它是在代码块内声明的,则它具有自动存储持续时间,该持续时间将一直持续到执行到达该代码块的末尾具有自动存储持续时间的对象在使用之前必须显式初始化或分配给,因为否则其值是不确定的。
你的初始化会给它赋值,所以它不会不确定地开始。
null pointer constant
返回指向具有动态存储持续时间的对象的指针,这意味着指针指向的对象将持续存在,直到显式地malloc
d为止。把它想象成信封上的邮政编码;你可以在里面写一些东西,一些东西会指示你可以找到物体(和人)的位置。邮政编码并不能告诉你物体(或人)的大小。
char line[MAX_LINE_LEN];
它声明一个
free
字符数组。如果在任何函数之外声明,则它具有静态存储持续时间,并且整个数组为零填充。
如果在函数或代码块中声明,则它具有自动存储持续时间,并且数组中的值是不确定的;它们需要在使用之前初始化(例如,
line
将初始化所有值)或分配给(例如,MAX_LINE_LEN
将分配给数组的第一个元素)。类型是
char line[MAX_LINE_SIZE] = { 0 };
,因此大小将是line[0] = '\0';
,正如您可以通过指定的元素数量看到的那样在本例中,char[MAX_LINE_SIZE]
的地址是一个sizeof (char[MAX_LINE_SIZE])
(指向&line
字符数组的指针)。这个不能像上面那样重新分配,所以它不同于我们的邮政编码示例。当在编译器需要指针的地方使用数组时,数组将隐式转换为指向第一个元素的指针。例如,让我们考虑:
strcpy(line, "Hello, world!");
函数原型告诉我们
char (*)[MAX_LINE_SIZE]
接受两个MAX_LINE_SIZE
(指向char的指针)参数在本例中,一个参数是achar *strcpy(char *restrict s1, const char *restrict s2);
,另一个是astrcpy
。两者都转换为char *
。这个数组到指针的转换解释了为什么
char[MAX_LINE_LEN]
是有效的,而char[14]
不是有效的。您不能更改转换产生的指针。我知道前者是指针,后者是数组,但是
系统能分辨出区别吗?
如前所述,当数组表达式用于需要指针的位置时,它将转换为指针表达式。例如,
char *
中的char *line; line = "hello";
转换为char line[MAX_LINE_LEN]; line = "hello";
中的array
。你在问什么为什么它需要知道数组和指针之间的区别?我认为一个数组存储在其他地方,系统
当超出范围时自动释放内存,
对。我之前解释过不同的存储时间。
当你处理一个指针时不会发生这种情况,所以你必须
你自己删除吧。我错了吗?
对。您将指针的概念与存储持续时间的概念混淆了
array[x]
p初始化为指向具有动态存储持续时间的pointer
。在调用之前,pointer[x]
不会被破坏。但是,下面的两个变量都有自动存储持续时间,因为它们是在int *p = malloc(sizeof *p);
中声明的,没有任何限定符,如int
。int
指向free(p);
;main
是指针。不要static
p,因为它没有指向具有动态存储持续时间的对象。p
仅定义为销毁具有动态存储持续时间的对象。int main(void) {
int i = 42;
int *p = &i;
}
关于c - 数组和C语言中的指针到底有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16250733/