【问题标题】:strange thing about calloc [duplicate]关于calloc的奇怪事情[重复]
【发布时间】:2017-01-04 22:23:47
【问题描述】:

我正在编写一些代码,我使用了函数calloc

我知道,当传递给该函数的第一个和第二个参数都为零时,该函数将为 0 个元素分配必要的空间,每个元素的大小为 0,但奇怪的是。

即使 n > 0,这个程序也能正常工作。为什么会这样?我认为它应该显示错误,因为我试图在不存在的数组位置写入。谢谢!

#include <stdio.h>
#include <stdlib.h>

int main(){
  int n;
  scanf("%d", &n);
  int *test = calloc(0, 0);
  for(int i = 0; i < n; i++){
    test[i] = 100;
    printf("%d ", test[i]);
  }
  return 0;
}

【问题讨论】:

  • 未定义的行为意味着任何事情都可能发生。
  • 没有语法错误 = c 中没有编译错误。你所编译的东西很好,但是你写的东西超出了你的内存区域(当n &gt; 0),这是未定义的行为。
  • 你不会在 c 中遇到这样的错误。它只会尝试将其写入指定的地址。作为程序员,你必须小心确保它不会发生。

标签: c calloc


【解决方案1】:

在 C 中,很多错误和“错误”的东西不会显示来自编译器的错误消息。事实上,当您运行程序时,您甚至可能看不到错误消息 - 但在另一台计算机上运行您的程序的其他人可能会看到错误。

C 中的一个重要概念称为未定义行为。简单来说就是你的程序的行为是不可预测的,但是你可以在这个问题中阅读更多关于这个主题的内容:Undefined, unspecified and implementation-defined behavior

您的程序未定义有两个原因:

  1. sizenmemb 为零时,calloc() 可能返回NULL。您的程序没有检查calloc() 的输出,因此当您执行test[i] 时,您很有可能试图取消引用NULL 指针——您应该始终检查calloc()malloc() 的结果.
  2. 当您调用malloc()calloc() 时,您实际上是在为数组分配动态内存。您可以使用指针来访问数组的元素。但是您无法访问数组过去中的任何内容。也就是说,如果您分配了n 元素,则不应尝试访问n+1-th 元素-- 用于读取。

以上两项都会使您的程序调用未定义的行为。除了上面列出的第 2 项之外,可能还有一些关于访问空对象的未定义,但我不确定。

您应该始终小心未定义的行为,因为当您的程序调用 UB 时,它本质上是不可预测的。您可以看到编译错误,程序可以给出错误消息,它可以成功运行而没有任何问题,或者它可以 清除硬盘中的每个文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 2011-07-03
    • 2020-11-18
    • 1970-01-01
    相关资源
    最近更新 更多