如果某个变量过去已经malloc
,那么如果再次呼叫realloc
而不是malloc
,会发生什么?它会导致内存泄漏吗?
我想知道,以便我可以在void memtest(char **foo)
{
if ( foo )
*foo = malloc(10); // Assuming *foo was already allocated in the past.
}
调用传递给函数的参数之前添加检查,以避免潜在的泄漏。
void memtest(char **foo)
{
if ( foo ) {
if ( *foo ) {
free(*foo);
*foo = NULL;
}
*foo = malloc(10);
}
}
我是否应该始终执行以下操作?
- (void)deleteDialogWithID:(NSString *)dialogId completion:(void (^)(QBResponse *))completion {
NSParameterAssert(dialogId);
__weak __typeof(self)weakSelf = self;
[QBRequest deleteDialogsWithIDs:[NSSet setWithObject:dialogId] forAllUsers:NO successBlock:^(QBResponse *response, NSArray *deletedObjectsIDs, NSArray *notFoundObjectsIDs, NSArray *wrongPermissionsObjectsIDs) {
//
[weakSelf.dialogsMemoryStorage deleteChatDialogWithID:dialogId];
[weakSelf.messagesMemoryStorage deleteMessagesWithDialogID:dialogId];
if ([weakSelf.multicastDelegate respondsToSelector:@selector(chatService:didDeleteChatDialogWithIDFromMemoryStorage:)]) {
[weakSelf.multicastDelegate chatService:weakSelf didDeleteChatDialogWithIDFromMemoryStorage:dialogId];
}
[weakSelf.loadedAllMessages removeObjectsForKeys:deletedObjectsIDs];
if (completion) {
completion(response);
}
} errorBlock:^(QBResponse *response) {
//
if (response.status == QBResponseStatusCodeNotFound || response.status == 403) {
[weakSelf.dialogsMemoryStorage deleteChatDialogWithID:dialogId];
if ([weakSelf.multicastDelegate respondsToSelector:@selector(chatService:didDeleteChatDialogWithIDFromMemoryStorage:)]) {
[weakSelf.multicastDelegate chatService:weakSelf didDeleteChatDialogWithIDFromMemoryStorage:dialogId];
}
}
else {
[weakSelf.serviceManager handleErrorResponse:response];
}
if (completion) {
completion(response);
}
}];
}
答案 0 :(得分:5)
如果*foo
的指针包含指向先前分配的内存的唯一指针,那么您刚刚泄漏了之前的内存。否则,它是完全无害的。
答案 1 :(得分:5)
对malloc
的调用无关紧要。
如果出现问题,问题就在于作业。完成x=42;
之后x
的前一个值已经消失,无论它有多重要。同样,如果foo
是唯一指向某个内存的指针,如果覆盖foo
,则无法再访问该内存。
如果没有指定要释放的内容,则无法致电free
。因此,如果你在丢失唯一指针之前没有释放内存,那么你就无法释放它,这就是内存泄漏的定义。
答案 2 :(得分:5)
没有“在变量上调用malloc
”。
malloc
找到一些“空闲”内存,将其标记为“已使用”,并返回刚刚找到的内存开头的地址。 free
将某些“已使用”的内存标记为“免费”。
运行时
*foo = malloc(10);
发生以下情况:
malloc
找到10个字节的可用内存。malloc
标记使用的那10个字节。malloc
返回刚刚找到的10个字节的开头地址。foo
的值,这是一个地址,因为foo
是指针。malloc
存储在foo
中存储的地址。 malloc
无关心你的程序对它返回的地址的处理方式。它不关心您的程序是将它存储在一个简单的变量,一个数组,另一个malloc
ed空间,还是将它写入文件。它甚至不关心你的程序是否忘记了地址,但你应该关心,因为如果程序不知道它试图释放的内存的地址,你的程序将永远无法调用free
。 p>
鉴于这些知识,你应该能够看到这段代码的作用:
char *bar;
bar = malloc(10);
bar = malloc(10);
free(bar);
花点时间弄明白,然后阅读以下内容:
bar
的变量。其类型为char*
。malloc
找到10个空闲字节并将其标记为已使用。malloc
返回10个字节的开头地址。malloc
中。 (bar
现在包含前10个字节的地址)bar
找到10个可用字节,并将其标记为已使用。malloc
返回10个字节的开头地址。malloc
中。 (malloc
现在包含第二个10字节的地址)bar
将后10个字节标记为空闲。这是内存泄漏。永远不会释放前10个字节。我可以告诉他们永远不会被释放,因为程序不知道他们在哪个地址。
但是这个节目怎么样?
bar
在这里,我在“已经保存了free
个地址的变量上调用了free
”。这是内存泄漏吗?不是单独的。该程序可能仍然是char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
第一个内存块,其地址仍存储在malloc
中。
但是,这肯定是内存泄漏:
malloc
我甚至没有改变代码,只是把它放在一个函数中,它现在是内存泄漏! Whaaaaaaaaa?
记住内存泄漏究竟是什么。内存泄漏是指程序分配内存但从不释放内存。您无法通过查看free
调用来判断程序是否释放了所有内存。
至于第二部分 - “我应该这样做吗?”
否,你不应该。
仅当传递给您的函数的地址的旧值是baz
ed指针,和,如果调用者忘记void func()
{
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
}
它时,它才会起作用。
您的建议将破坏以下任何功能:
malloc
总之:标题中的问题没有意义。检测内存泄漏并不像这样简单。而你想要做的是一个坏主意。
答案 3 :(得分:3)
导致内存泄漏,因为先前分配的内存未被任何变量引用而您丢失了其地址。
没有具体检查。您可以在声明时将指针设置为NULL
,并在每次内存NULL
时将其设置为free
。然后,您可以在if (pointer == NULL)
之前检查malloc
。
使用realloc
可以避免内存泄漏问题,因为如果指针是空指针,realloc
函数的行为类似于指定大小的malloc
函数。但如果您的指针未声明设置为NULL
,则可能会导致问题。
即:
int *foo = NULL;
void bar( void )
{
foo = realloc(foo, 10*sizeof(int));
}
realloc的一个好或坏特征是它保留了你记忆的内容。
我是否应该始终执行以下操作?
void memtest(char **foo)
{
if ( *foo )
free(*foo);
*foo = malloc(10);
}
不,你不应该因为free
没有将指针设置为NULL
,并且你的指针仍然具有已经free
内存的值程序中断错误。
我的意思是,如果您在代码中某处free
指针而不重新分配它,则此类代码容易出错。
并且您必须确保将指针声明为NULL
作为初始值。
答案 4 :(得分:1)
在现有变量上调用
malloc
会发生什么?
几乎没有可能:
malloc
成功分配了内存,则重新分配内存将导致内存泄漏。 malloc
调用的内存分配失败,那么就不会有内存泄漏。 我是否应该始终执行以下操作?
void memtest(char **foo) { if ( *foo ) free(*foo); *foo = malloc(10); }
是。通过这种方式,您可以确保没有内存泄漏。