[英]Native node.js addon error pointer being freed was not allocated
我正在寫一個看起來像這樣的函數:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
//TODO this is causing `malloc: *** error for object 0x10a202000: pointer being freed was not allocated`
char * iconBuff = (char *)[tiffData bytes];
Nan::MaybeLocal<v8::Object> ret = Nan::NewBuffer(iconBuff, length);
return ret;
}
它按預期工作,除非它由node.js運行時,它拋出malloc: *** error for object 0x10a202000: pointer being freed was not allocated
。 我嘗試使用malloc
等進行其他操作,但是沒有任何效果。 我知道Nan::NewBuffer
試圖以某種方式釋放緩沖區數據,而這正是問題所在。 也許iconBuff
變量已分配給堆棧,並且當它超出范圍並且Nan::NewBuffer
試圖釋放它時,它正在釋放空指針? 我不確定,我有點迷失了:(
這是“修復”它的代碼,但是@uliwitness在他的回答中指出它仍然存在內存管理問題:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
char * iconBuff = new char[length];
[tiffData getBytes:iconBuff length:length];
Nan::MaybeLocal<v8::Object> ret = Nan::NewBuffer(iconBuff, length);
return ret;
}
這是我根據@uliwitness的答案最終得到的特定代碼:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
@autoreleasepool {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
return Nan::CopyBuffer((char *) [tiffData bytes], length);
}
}
這似乎是最優雅的解決方案,並且經過一些快速,骯臟的測試,似乎可以使許多調用中的node.js駐留集大小變小,無論它是值得的。
我搜索了有關Nan::NewBuffer
文檔,並找到了以下頁面: https Nan::NewBuffer
這說:
請注意,使用Nan :: NewBuffer()和現有char *創建一個Buffer時,假定指針的所有權已轉移到新的Buffer進行管理。 當node :: Buffer實例被垃圾回收並且未指定FreeCallback時,將通過調用free()處理數據。 以這種方式創建了Buffer后,一定不能手動釋放內存空間。
因此,您自己的答案中的代碼是錯誤的,因為使用new char[]
創建的緩沖區需要使用delete []
(這與delete
,FWIW不同),但是您將其提供給了一個承諾打電話free
。 您只是不小心關閉了錯誤消息,而沒有解決錯誤。
因此至少,您應該使用malloc
代替new
。
該頁面還提到了另一個函數Nan::CopyBuffer()
,它描述為:
類似於Nan :: NewBuffer(),不同的是,隱式memcpy將在Node中發生。 調用node :: Buffer :: Copy()。 char *的管理權留給用戶使用,由於新的Buffer將擁有其自己的副本,因此如有必要,您應該手動釋放內存空間。
對於您的原始代碼,這聽起來是一個更好的選擇。 您可以將其傳遞給NSData
的bytes
,甚至可以為您進行復制。 您不必擔心“手動釋放內存空間”,因為內存由NSData擁有,它將在釋放時負責處理它(如果您使用的是ARC,ARC將釋放NSData。 ,如果您不是ARC,則應添加一個@autoreleasepool
以便將其釋放)。
PS-在該頁面的底部,它還提到您可以使用Nan::FreeCallback
並將其傳遞給Nan::NewBuffer
。 如果您在其中提供一個在給定的緩沖區上調用delete []
的方法,則答案中的代碼也將起作用。 但是,實際上,為什么還要為Nan::CopyBuffer
寫一些額外的代碼,顯然已經為您完成了呢?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.