指针、malloc 和编译
Pointers, malloc and Compilation
我试图弄清楚指针是如何为它们分配内存并声明它们的,虽然我有点知道它们是如何工作的,但我仍然感到困惑,我不确定是否是因为我的编译器什么的。
我目前默认使用带 GNU/GCC 编译器的 CodeBlocks,这是我 运行:
的代码
#include <stdio.h>
int main()
{
int a = 2;
int *b = 5;
printf("%d\n", a);
printf("%d\n", b);
}
问题是这两个都写出正确的结果,如果我可以写出*b = 5
并这样声明,为什么我需要使用malloc
,不是目的吗malloc
的内存分配给指针,以便您可以在之后声明它?
是编译器错误允许它编译还是我只是没有理解 malloc
的要点?
The problem is that both of these write out correct result, why would I need to use malloc if I can just write out *b = 5 and declare it like that, isn't the purpose of malloc to allocate memory to a pointer so you can declare it after?
您可以将指针写入您已经知道 data/code 存在的现有内存中。在您的情况下,您只是将指针指向 5.. 而您不知道内存地址 5.
我认为您对内存分配的实际作用有点困惑。它并没有神奇地让内存出现供您使用,它使用称为堆的东西使内存可以访问,也就是 read/write 并且取决于您授予的权限可能是可执行的。您分配内存以便可以使用该内存区域。如果您不分配内存而只是访问随机内存区域,您将不知道会发生什么。它很可能会崩溃。但您也可以是 accessing/overwriting 流程的现有关键信息。
让我们假设调用 malloc
returns 地址 0xCAFE。这意味着我们可以访问地址或内存区域。但是我们知道 0xCAFE 已经存在于进程内存中,我们可以不直接指向它并使用它吗?不,因为您不知道该区域是否可访问或者它是否已经被使用(通过先前调用 malloc 分配)或者它可能在将来使用(通过未来调用 malloc 分配),您将在其中得到在损坏的内存中。
结果如您所愿并不意味着代码是正确的,您的程序格式错误,在 int *b = 5
中,您将值 5 赋给一个指针,这将被解释为内存地址,这就是指针的用途,因此您可以使用该内存地址来访问数据,例如,将其作为函数参数传递,以便可以操作数据。
如果你只想存储一个 int
你会使用一个 int
变量,所以虽然不违法,但它没有多大意义,并且引用指针将调用未定义的行为, 所以你不能真正将它用作指针,它就是这样。
你使用malloc
这样你的程序和那个特定的指针可以被系统给(分配)一个可用的内存地址,你可以在其中存储数据供以后使用,(5
几乎当然不是那样)。
printf("%d\n", b)
也不正确,打印指针值的说明符即内存地址是%p
, 这绝对是未定义的行为,正确的表达方式是:
printf("%p\n", (void*)b);
C 为程序员提供了做其他编程语言不允许做的事情的余地,这是一个优势,但它也可能是一个问题,编译并似乎 运行 正确的程序可能有问题.当格式错误的程序符合 运行 时,其行为属于 undefined behavior.
的类别
这是在标准中定义的,它赋予编译器以任何它认为合适的方式处理代码的自由裁量权,包括产生看似正确的结果,问题是这可能今天有效,明天崩溃或反之亦然-相反,它完全不可靠。
我试图弄清楚指针是如何为它们分配内存并声明它们的,虽然我有点知道它们是如何工作的,但我仍然感到困惑,我不确定是否是因为我的编译器什么的。
我目前默认使用带 GNU/GCC 编译器的 CodeBlocks,这是我 运行:
的代码#include <stdio.h>
int main()
{
int a = 2;
int *b = 5;
printf("%d\n", a);
printf("%d\n", b);
}
问题是这两个都写出正确的结果,如果我可以写出*b = 5
并这样声明,为什么我需要使用malloc
,不是目的吗malloc
的内存分配给指针,以便您可以在之后声明它?
是编译器错误允许它编译还是我只是没有理解 malloc
的要点?
The problem is that both of these write out correct result, why would I need to use malloc if I can just write out *b = 5 and declare it like that, isn't the purpose of malloc to allocate memory to a pointer so you can declare it after?
您可以将指针写入您已经知道 data/code 存在的现有内存中。在您的情况下,您只是将指针指向 5.. 而您不知道内存地址 5.
我认为您对内存分配的实际作用有点困惑。它并没有神奇地让内存出现供您使用,它使用称为堆的东西使内存可以访问,也就是 read/write 并且取决于您授予的权限可能是可执行的。您分配内存以便可以使用该内存区域。如果您不分配内存而只是访问随机内存区域,您将不知道会发生什么。它很可能会崩溃。但您也可以是 accessing/overwriting 流程的现有关键信息。
让我们假设调用 malloc
returns 地址 0xCAFE。这意味着我们可以访问地址或内存区域。但是我们知道 0xCAFE 已经存在于进程内存中,我们可以不直接指向它并使用它吗?不,因为您不知道该区域是否可访问或者它是否已经被使用(通过先前调用 malloc 分配)或者它可能在将来使用(通过未来调用 malloc 分配),您将在其中得到在损坏的内存中。
结果如您所愿并不意味着代码是正确的,您的程序格式错误,在 int *b = 5
中,您将值 5 赋给一个指针,这将被解释为内存地址,这就是指针的用途,因此您可以使用该内存地址来访问数据,例如,将其作为函数参数传递,以便可以操作数据。
如果你只想存储一个 int
你会使用一个 int
变量,所以虽然不违法,但它没有多大意义,并且引用指针将调用未定义的行为, 所以你不能真正将它用作指针,它就是这样。
你使用malloc
这样你的程序和那个特定的指针可以被系统给(分配)一个可用的内存地址,你可以在其中存储数据供以后使用,(5
几乎当然不是那样)。
printf("%d\n", b)
也不正确,打印指针值的说明符即内存地址是%p
, 这绝对是未定义的行为,正确的表达方式是:
printf("%p\n", (void*)b);
C 为程序员提供了做其他编程语言不允许做的事情的余地,这是一个优势,但它也可能是一个问题,编译并似乎 运行 正确的程序可能有问题.当格式错误的程序符合 运行 时,其行为属于 undefined behavior.
的类别这是在标准中定义的,它赋予编译器以任何它认为合适的方式处理代码的自由裁量权,包括产生看似正确的结果,问题是这可能今天有效,明天崩溃或反之亦然-相反,它完全不可靠。