【问题标题】:Simulating failure of calloc by setting char pointer to NULL通过将 char 指针设置为 NULL 来模拟 calloc 的失败
【发布时间】:2015-08-04 21:15:53
【问题描述】:

**** 这个问题很困惑,因为我在程序中遗漏了一些东西,但是这个问题的答案很有见地(无论如何对我来说)。如果您遇到类似的问题,我建议您专注于答案而不是我的代码****

我正在尝试编写一个程序,该程序可以通过通知用户失败来处理内存分配失败,但要解决它。 (我知道在大多数情况下这不是正确的做法)。

我有一个结构。它的结构变量之一是:

char* name;

在某些时候,我有以下行,为这个变量动态分配内存并将其设置为某个输入:

if(object->name = calloc(1, strlen(input)+1)){
    strcpy(object->name, input);
}

我想在 calloc 无法分配内存的情况下检查程序的行为。我写了一个测试,将上面的代码行替换为:

object->name = NULL; //instead of the calloc

因为我认为如果 calloc 分配内存失败,它将返回 NULL。

但是,当我这样做时,我在那条线上遇到了分段错误。我认为这是因为我没有为 object->name 分配内存。然而,这正是我的观点。我只想将指向 char 数组的指针设置为 NULL。我想稍后在程序的某个地方检查这个 NULL 指针并解决它。

如何使 object-> 命名为 NULL 指针而不会出现分段错误?


因为我没有在上面包含足够的细节,这是实际的代码:

 //disk is the "object" in question
if(disk_ptr = calloc (1, sizeof (disk))){
        disk_created_successfully = set_or_fix_disk_static_attributes_test_all_is_null(&disk_ptr, name);
        ...
}

在哪里

bool set_or_fix_disk_static_attributes_test_all_is_null(disk** disk_ptr, char* name){
    int success = true;
    (*disk_ptr)->name = NULL;
    // Code fails here
    ...
    return success;
}

【问题讨论】:

  • 我读了你问题的最后一句话,重新读了一遍,我仍然一无所知。 :-( 实际上,您期望的区别是什么?
  • 抱歉,马上编辑。我明白你的意思了。
  • 或者,也许我们在这里遗漏了一个简单的事情,即在执行object->name = NULL; 时,object 本身是 NULL 还是无效?
  • 我认为最好显示 where 您正在设置 NULL 值。我怀疑你在if 中这样做,从而写入strcpy 中的未分配内存或制造其他类似的“混乱”
  • @Amit 在这种特殊情况下,if (<NULL>) 将阻止strcpy(),但我们不知道完整的代码。

标签: c pointers memory memory-management


【解决方案1】:

为了测试条件,你可以改变

if(object->name = calloc(1, strlen(input)+1)){
    strcpy(object->name, input);
}

到

if (0) {
    strcpy(object->name, input);
}

也就是说,您的原始代码正在检查分配是否成功。它失败的结果是“假”是条件。

可能还有其他代码使用object->name,所以更全面的测试是:

if (object->name = NULL) {
    strcpy(object->name, input);
}

【讨论】:

  • 附带说明,不要将= 与== 混淆。我们没有将object->name 与NULL 进行比较,事实上我们并没有隐含地比较任何东西。这种情况下的行为是这个if () 语句将传递任何非零值。假设NULL 指针在算术上等价于0,如果object->name 是NULL,if () 语句将不会通过。
【解决方案2】:

据我从您的 sn-p 中可以看出,如果 object 分配了 peroper 内存,

 object->name = NULL;

很好并且合法。但是,在这种情况下,在以后的任何时候,任何类似于

的代码
 strcpy(object->name, input);

将是非法的,因为您实际上是在尝试写入无效内存。一般来说,任何后续对object->name的读写访问都应该被阻止。


编辑:

我觉得你有点困惑。正如您的帖子所说,如果您尝试模拟calloc() 故障,那么您必须将disk_ptr 设置为NULL。然后,在set_or_fix_disk_static_attributes_test_all_is_null() 函数内部,指令

(*disk_ptr)->name = NULL;

变得无效,因为您将取消引用 NULL 指针。您可能需要先添加一个针对 NULL 的 *disk_ptr 检查。

【讨论】:

  • 是的 - 我在后面的代码中使用 object->name 没有检查 NULL。谢谢。
【解决方案3】:

您需要在调用calloc 后立即测试NULL 指针。如果您在任何时候引用该 NULL 指针,您就是在自找麻烦。

在这种情况下,这将在您手动将指针设置为 NULL 之后。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2017-09-05
    • 1970-01-01
    • 2018-08-06
    • 2013-08-21
    • 2016-03-01
    • 2010-10-16
    相关资源
    最近更新 更多