Objective c 如何释放通过引用传递给c代码且其成员为malloc';你在那里见过他吗?
我在尝试释放在c函数中分配的对象的内存(在objective-c代码中)时遇到“malloc:*对象0xbfffe160的错误:未分配要释放的指针”。此C函数创建并返回二进制数据包,稍后用作NSData。下面是我的obj-c代码部分,我在其中创建struct变量并通过引用将其传递给c函数: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
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
是错误的&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
是错误的&x
是“x的地址”,而不是“对x的引用”
让我们考虑下面的代码:
char *x = malloc(10);
free(x);
当人们谈论这段代码时,他们会说类似于“x
在堆上分配”,但这在技术上是不正确的,x
在堆栈上分配,并且包含堆上10个字节的地址。同样,行free(x)
实际上并不释放x