Objective c 如何释放通过引用传递给c代码且其成员为malloc';你在那里见过他吗?

Objective c 如何释放通过引用传递给c代码且其成员为malloc';你在那里见过他吗?,objective-c,c,Objective C,C,我在尝试释放在c函数中分配的对象的内存(在objective-c代码中)时遇到“malloc:*对象0xbfffe160的错误:未分配要释放的指针”。此C函数创建并返回二进制数据包,稍后用作NSData。下面是我的obj-c代码部分,我在其中创建struct变量并通过引用将其传递给c函数: MyPacket packetRef; allocAuthentificationCodePacket(&packetRef); NSData *data = [NSData dataWithByt

我在尝试释放在c函数中分配的对象的内存(在objective-c代码中)时遇到“malloc:*对象0xbfffe160的错误:未分配要释放的指针”。此C函数创建并返回二进制数据包,稍后用作NSData。下面是我的obj-c代码部分,我在其中创建struct变量并通过引用将其传递给c函数:

MyPacket packetRef;
allocAuthentificationCodePacket(&packetRef);

NSData *data = [NSData dataWithBytes:packetRef.bytes length:packetRef.packet->packetSize];
free(&packetRef); // getting error
一切正常,除了我试图释放内存,因为数据应该由NSData变量保留。C函数在其内部执行calloc,因此我应该以某种方式释放内存:

packetRef->bytes = calloc(1, sizeof(*packetRef));
以下是我存储二进制数据的结构:

typedef struct {

  uint8_t packetType;
  uint16_t packetBody;

} MyStruct;
和另一个结构:

typedef union {

  const uint8_t *bytes; 
  MyStruct *packet;

} MyPacket;
我应该如何释放内存?我得到的错误不是崩溃,它只是运行单元测试时调试控制台中的一条消息

更新。试图释放“bytes”结构成员,但收到相同的错误消息:

free(&packetRef.bytes);
更新2。谢谢,建议的方法确实有效,并且malloc错误消息从控制台中消失:

free(packetRef.bytes);

但是,在Xcode中获得警告“将'const uint8_t*'(也称为'const unsigned char*)传递给'void*'类型的参数将丢弃限定符”。我正在使用Apple LLVM 4.1编译器。C函数驻留在单独的文件中,只包含一个头文件,因为Android人员将不得不重用它


更新3。感谢@simonc和@nos指出结构成员“bytes”具有常量。删除常量后,警告已消失。使用const的最初想法是保护“bytes”不被修改。

packetRef
在您的示例中是一个堆栈变量,分配了
packetRef->bytes
堆。因此,您应该调用
free(packetRef.bytes)

由于在函数中分配内存-
allocAuthentificationCodePacket
,因此可能需要创建另一个函数来释放内存

void freePacket(MyPacket* packet)
{
    free(packet->bytes);
}

packetRef
在您的示例中是一个堆栈变量,分配了
packetRef->bytes
堆。因此,您应该调用
free(packetRef.bytes)

由于在函数中分配内存-
allocAuthentificationCodePacket
,因此可能需要创建另一个函数来释放内存

void freePacket(MyPacket* packet)
{
    free(packet->bytes);
}
这总是错误的。(提示:将
&
放在
free()
中几乎总是错误的)

无论什么是
MyPacket
,它都具有自动存储持续时间,即当函数退出时,编译器自动分配存储并释放存储

不要
free()
任何东西,除非它来自
malloc()
(或
calloc()
等)

由于
packetRef.bytes
是用
calloc()
分配的,因此您可以用
free()
代替它

MyPacket packetRef;
allocAuthentificationCodePacket(&packetRef);
...
free(packetRef.bytes);
更新 如果调用的函数AllocAuthenticationCodePacket包含以下代码:

packetRef->bytes = calloc(1, sizeof(*packetRef));
如果
bytes
字段的类型为
const uint8*
,则说明有问题

  • 也许您的代码是错误的,您应该调用一些函数来释放数据包,而不是自己释放它

  • 也许
    字节
    字段的类型是错误的,应该是
    uint8\u t*
    而不是
    const uint8\u t*

  • 也许
    allocauthentificationcodepack
    是错误的

  • 谁知道呢?撞车还不够错误,但这是个问题

    脚注 C中没有引用。
    &x
    是“x的地址”,而不是“对x的引用”

    让我们考虑下面的代码:

    char *x = malloc(10);
    free(x);
    
    当人们谈论这段代码时,他们会说类似于“
    x
    在堆上分配”,但这在技术上是不正确的,
    x
    在堆栈上分配,并且包含堆上10个字节的地址。同样,行
    free(x)
    实际上并没有释放
    x
    ,而是释放
    x
    指向的内存

    因此,当有人告诉你,“不要忘记释放
    x
    ”,你知道他们实际上是指“不要忘记释放
    x
    中包含的值指向的内存”。人们对术语的理解很草率,但计算机却不是。这总是错误的。(提示:将
    &
    放在
    free()
    中几乎总是错误的)

    无论什么是
    MyPacket
    ,它都具有自动存储持续时间,即当函数退出时,编译器自动分配存储并释放存储

    不要
    free()
    任何东西,除非它来自
    malloc()
    (或
    calloc()
    等)

    由于
    packetRef.bytes
    是用
    calloc()
    分配的,因此您可以用
    free()
    代替它

    MyPacket packetRef;
    allocAuthentificationCodePacket(&packetRef);
    ...
    free(packetRef.bytes);
    
    更新 如果调用的函数AllocAuthenticationCodePacket包含以下代码:

    packetRef->bytes = calloc(1, sizeof(*packetRef));
    
    如果
    bytes
    字段的类型为
    const uint8*
    ,则说明有问题

  • 也许您的代码是错误的,您应该调用一些函数来释放数据包,而不是自己释放它

  • 也许
    字节
    字段的类型是错误的,应该是
    uint8\u t*
    而不是
    const uint8\u t*

  • 也许
    allocauthentificationcodepack
    是错误的

  • 谁知道呢?撞车还不够错误,但这是个问题

    脚注 C中没有引用。
    &x
    是“x的地址”,而不是“对x的引用”

    让我们考虑下面的代码:

    char *x = malloc(10);
    free(x);
    
    当人们谈论这段代码时,他们会说类似于“
    x
    在堆上分配”,但这在技术上是不正确的,
    x
    在堆栈上分配,并且包含堆上10个字节的地址。同样,行
    free(x)
    实际上并不释放
    x