【问题标题】:Confused with accessing malloc memory (Uninitialized)对访问 malloc 内存感到困惑(未初始化)
【发布时间】:2013-07-15 06:17:16
【问题描述】:

声明简单结构:

struct s {
    char* addr;
};

s *ips;

现在分配结构数组内存

num = 5
ips = (r *) malloc(num * sizeof(r));

我知道 malloc 只是分配内存,并没有初始化,可能会有垃圾值。

现在我想知道如果我不初始化一个,并尝试访问会发生什么?

//Init for 4 of them
for(int i = 0; i < num-1; i++)
    ips[i].addr = strdup("123");

//Accessing un-initialize one:
if(ips[4].addr) {
    printf("Accessing uninitialize one and lets say freeing!!!");
    free(ips[4].addr);
}

理想不应该进入这个 for 循环。但后来我认为可能是因为垃圾价值。我不确定!

【问题讨论】:

  • 恭喜!您已经问过第 1,000,000 个“当我调用未定义的行为时会发生什么?”题!您的 C 标准免费副本已在邮件中。
  • 只要你写的代码不会编译你就应该是安全的。
  • 与 sizeof(r) 而不是 s 配合得非常好 :)
  • 不要对 malloc() 返回地址进行类型转换

标签: c malloc


【解决方案1】:

初始化你的变量。

没有初始化 - 所有赌注都关闭。
ips[4].addr,正如您知道,未初始化。所以使用:

// Various code
...
if(ips[4].addr) {

是一种复杂的简单询问方式,以下是做什么的?

int i;
if (i) {

每次运行程序时i 的值都可能相同。如果可以不一样。没有应该发生的事情的理想。这是简单的未定义行为 (UB)。

【讨论】:

    【解决方案2】:

    将会发生什么将是不可预知的,因为您无法知道内存包含什么。您应该使用calloc 而不是malloc,或者在调用malloc 后使用memset 内存。

    就我个人而言,我更喜欢使用calloc,因为它可以节省一行代码,并且让以后更容易阅读您的代码。

    【讨论】:

    • callocmemset 都不能保证将指针设置为 null,或将浮点对象设置为 0.0
    • @Keith Thompson 你断言calloc() 不保证 NULL 或 0.0,是虽然内存是零填充的,但 NULL 和 0.0 可能不只是由零组成位?还是有别的?
    • @chux:就是这样。在最常见的实现中,空指针和浮点 0.0 都表示为全位为零,但 C 标准不保证这一点。如果您要编写依赖于该假设的代码,我建议至少明确假设。 (我不想依赖它;例如,const foo_t foo_zero = { 0 }; 为您提供了一个 foo_t 类型的对象,所有成员都设置为零(整数 0,浮动 0.0,空指针,...)。
    • @KeithThompson - 谢谢,我不知道,但 IEEE-754 标准不涵盖存储格式吗? AFAIK 这涵盖了二进制表示,所以如果编译器支持 IEEE-754(现在大多数都支持),这应该不是问题。
    • @Geoffrey:我认为是这样,但 C 不需要 IEEE-754 合规性。您做出的假设越少,在追踪不可避免的错误时需要考虑的事情就越少。
    猜你喜欢
    • 2021-08-11
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2013-02-17
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    相关资源
    最近更新 更多