【问题标题】:Is there any difference on allocating memory like this?像这样分配内存有什么区别吗?
【发布时间】:2020-10-03 22:08:44
【问题描述】:

我想我有一个初学者的疑问。我不知道这是不是一个很愚蠢的问题,但这两种情况有什么区别:

通用结构:

typedef struct {

    void* data;

} Object;

第一种情况:这种情况在指针上分配内存,然后返回指针。

Object* NewObject1(const void* data) {

    Object* This = (Object*)malloc(sizeof(Object));
    memcpy_s(&This->data, sizeof(void**), &data, sizeof(void**));

    return This;
}

第二种情况:在这种情况下,内存分配在用户指定的指针上。

void NewObject2(Object** This, const void* data) {

    *This = (Object*)malloc(sizeof(Object));
    memcpy_s(&(*This)->data, sizeof(void**), &data, sizeof(void**));

}

结果,其实是一样的:

int main(){

    Object* a = NewObject1((void*)10);
    printf("a->data = %d\n", (int)a->data);

    Object* b = NULL;
    NewObject2(&b, (void*)10);
    printf("b->data = %d\n", (int)b->data);

    return 0;
}

输出:

a->data = 10
b->data = 10

所以我的问题是:在第一种情况或第二种情况下分配内存之间有任何真正的区别。比如内存安全、性能等。

【问题讨论】:

  • 两者的内存分配是一样的,唯一的区别是一个你返回一个指针,另一个你传入一个指向指针的指针并将它设置在那里。除了代码的清晰性之外,没有任何区别。

标签: c memory memory-management heap-memory low-level


【解决方案1】:

这两种返回值的方法相同。您可以按值返回,也可以使用指向应写入“返回”值的位置的指针参数。

但是,您的代码还有其他一些奇怪的地方:

  • 你应该分别写This->data = data;(*This)->data = data;而不是memcpy_s。并修复 const 正确性。
  • (void *)10 可能不是有效地址,这可能会导致陷阱、总线错误或其他问题。 (如果不是实际对象的地址,则为未定义行为)
  • 强制转换 malloc 的结果是多余的或更糟。
  • 应该检查 malloc 的返回值。

【讨论】:

  • 但我使用(void*)10 作为值,而不是地址。这是一个坏习惯还是一个错误?
  • C 标准:“6.3.2.3:5 整数可以转换为任何指针类型。除非前面指定,结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,可能是陷阱表示。"
  • 如果要将不同类型存储到同一字段中,请使用联合。
  • @PaulHankin 或 uintptr_t 如果指针和整数是唯一要求
  • @M.M 不能保证转换 uintptr_t 并返回会保留我认为的值?只有当您将 void* 转换为 uintptr_t 并返回时,您会得到相同的指针。
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2020-10-26
  • 2018-12-29
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多