关于以下代码的两个问题:
有和没有
malloc()
语句的区别是什么:p = (char *) malloc (20 * sizeof(char) );
仅仅是内存位置的不同吗?指针变量 '
p
' 在没有该语句的情况下处于 STACK 中,而在具有该语句的 HEAP 中?为什么声明是
printf("%s\n", p);
不是
printf("%s\n", *p);
#include <stdlib.h>
#include <stdio.h>
int main () {
char movie[] = "forrest gump";
char *p;
p = (char *) malloc (20 * sizeof(char) );
p = movie;
printf("%p\n", p);
printf("%p\n", movie);
printf("%s\n", p); // to print "forrest gump"
free(p);
return 0;
}
最佳答案
问题一
添加了行号注释的代码:
char movie[] = "forrest gump"; // 1
char *p; // 2
p = (char *) malloc (20 * sizeof(char) ); // 3
p = movie; // 4
printf("%p\n", p); // 5
printf("%p\n", movie); // 6
printf("%s\n", p); // to print "forrest gump" // 7
free(p); // 8
我将忽略未检查 malloc()
的返回值,并且我不会被 malloc()
的返回值强制转换为 long如果您省略 malloc()
的声明,您的编译器会告诉您 — 但有很多人不同意这一点。 * sizeof(char)
不是必需的,最好写成 * sizeof(*p)
。
代码有内存泄漏,并且由于内存泄漏而表现出未定义的行为。
第 1 行没问题。第 2 行同样很好,尽管可以通过将它与第 3 行组合来初始化变量。
第 3 行在这种情况下是安全的,但分配的固定大小在其他情况下会成为问题。
第 4 行是一个主要问题。这是泄漏。您刚刚践踏了指向由 malloc()
返回的内存的唯一指针,因此内存不可挽回地丢失了。诚然,这个程序很快就会退出(如果它没有先崩溃的话),但总的来说,这很糟糕。你应该写:
strcpy(p, movie);
或者也许:
memmove(p, movie, sizeof(movie));
第 5 行将打印存储在 p
中的地址。正如所写的那样,这是 movie
的地址,因为第 4 行中的赋值。可以说,它应该用强制转换来编写,因为 %p
格式说明符采用 无效 *
:
printf("%p\n", (void *)p);
在实践中,当 p
是一个 char *
时,您将无处不在。我学会了在一台机器上编程(在有 C 标准之前的日子里),其中 char *
地址的位表示与 anything_bigger *
地址不同相同的内存位置。在这样的机器上,如果代码正在处理 struct Something *
甚至是 int *
,则必须转换为 void *
。
第 6 行产生与第 5 行相同的输出,并具有相同的注意事项。
第 7 行没问题,打印出 p
指向的数据,也是 movie
指向的数据。
第 8 行是调用未定义行为的地方。由于第 4 行中的分配,您试图释放未分配的空间,这是一场严重的灾难。它通常会导致崩溃;这绝不是一个好主意。
代码应该貌似是:
char movie[] = "forrest gump";
char *p = malloc(sizeof(movie)); // or: char *p = malloc(strlen(movie) + 1);
if (p != 0)
{
strcpy(p, movie);
printf("%p\n", p);
printf("%p\n", movie);
printf("%s\n", p);
free(p);
}
问题2
您的问题 2 是关于:
printf("%s\n", p);
printf("%s\n", *p);
第一个是正确的。 p
是一个 char *
,%s
转换规范需要一个 char *
。第二个不正确,因为 *p
是一个 char
,但 %s
需要一个 char *
。相反,它获取一个小整数(如果您的代码集基于 ASCII,则为 102)并尝试将其视为地址。这是行不通的;它通常会导致崩溃,因为整个第一页内存(1 KiB 或 4 KiB)通常被映射为无效。
你可以使用:
printf("%c\n", *p);
这将打印 f
。
关于C:指针题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28007356/