使用 malloc 将值分配给 C 指针,而无需变量初始化



从这个问题中,我明白了为什么下面的代码可能不起作用:

int *ptr;
*ptr = 1000;
printf("%d", *ptr);

当我使用以下方法编译和运行时:gcc file.c; ./a.out我得到:

分段错误(核心转储)./a.out

此处的 PTR 可能指向没有初始化变量的随机位置。这是对的吗?

但是,使用malloc()时不会出现此问题。

int *ptr = malloc(sizeof(int));
*ptr = 1000;
printf("%d", *ptr);

malloc 是否初始化其指针指向的变量?

简短回答:否

malloc 不初始化变量。它只是分配内存。您可以将整数放入函数中,例如malloc(8),它将只分配 8 个字节供以后使用。如果你进一步研究 malloc 函数,它实际上返回void*数据类型。以后可以将其类型转换为其他数据类型。

从您的代码malloc(sizeof(int)),实际上sizeof(int)返回一个整数,表示您放入其中的数据类型/变量的大小。

您链接的帖子或多或少地解释了它。一件事是没有涉及的是未定义的行为 - 这正是您的版本中将发生的情况,无需malloc

如果你尝试使用这样的指针,各种各样的事情都可能出错 - 你还没有说它应该指向哪里。它几乎可以指向任何地方。

这一行:

int *ptr = malloc(sizeof(int));

确实是一种初始化。这里发生的事情是两件事:(1)malloc在内存中保留空间,以便您随后可以使用指针,以及 (2) 它返回该内存的起始地址。

地址被分配给ptr- 它本身就是一个变量。而且,像所有变量一样,您不能在未初始化的情况下使用它们。如果这样做,则为无效代码,因此会导致未定义的行为。

让我们进一步深入到这一点:

如果不调用malloc,则指针无效,不应使用。为了证明这一点,请尝试编译您的代码,例如使用旧的gcc

如果运行:

gcc program.c  # no flags

它会编译 - 但仅仅因为gcc给了你一个二进制文件,并不意味着它会做你想做的事。当你运行它时,它会(大多数时候)惨败。

但是,如果运行:

gcc -Wall program.c  # enable warnings

它会警告ptr未初始化未使用。但是,它仍然会产生一个你可以运行的二进制文件 - 结果和以前一样。

最后,如果您运行:

gcc -Wall -Werror program.c  # enable warnings and turn them into errors

它会再次警告你同样的事情,但这一次,它不会产生二进制文件——而这正是你在这种情况下真正想要的。在这里,gcc告诉你,有些事情真的非常错误,你的代码根本无效。

现在,回到关于未定义行为的观点。一旦你编译了无效的代码(使用前两种方法中的任何一种 - 顺便说一句,请不要这样做),运行它通常会给你一个"分段错误"(seg 错误)。但是,它不必这样做,也不能保证您的程序将做什么。所有变量(包括指针)都需要初始化。

顺便说一句,如果你看这篇文章,它会告诉你为什么你需要在这里调用malloc- 这是因为你正在动态分配内存,所以它将在堆中而不是在堆栈上。

案例 I
Code:

int *ptr;
*ptr = 1000;

*ptr表示您正在取消引用ptr指针。取消引用未初始化的指针是未定义的行为。未定义的行为包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能偶然地完全按照程序员的意图执行。

案例二
代码:

int *ptr = malloc(sizeof(int));
*ptr = 1000;

malloc分配内存块(大小以字节为单位),并在成功时返回指向新分配内存开头的指针。新分配的内存块初始化。

执行此操作时:

int *ptr = malloc(sizeof(int));

假设malloc调用成功,并且它返回指向新分配内存开头的指针。此返回的指针将分配给ptr指针。因此,现在ptr指针已初始化,尽管它指向的内存未初始化
由于ptr指针指向有效的内存位置,因此您可以取消引用并访问它。

在此声明中

*ptr = 1000;

取消引用ptr并将1000分配给该内存位置。现在,指针指向ptr内存位置包含值1000。访问此值完全可以。

<小时 />

附加:

遵循良好的编程实践 - 始终检查malloc返回。你应该做:

int *ptr = malloc (sizeof (int));
if (NULL == ptr) {
exit(EXIT_FAILURE); // or whatever you want to do at malloc failure do it here
}

相关内容

  • 没有找到相关文章

最新更新