0

在过去的几个小时里,我一直在试图找到我的代码中的内存泄漏。这里是:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

expression = [expression stringByTrimmingCharactersInSet:
              [NSCharacterSet whitespaceAndNewlineCharacterSet]]; // expression is an NSString object.

NSArray *arguments = [NSArray arrayWithObjects:expression, [@"~/Desktop/file.txt" stringByExpandingTildeInPath], @"-n", @"--line-number", nil];
NSPipe *outPipe = [[NSPipe alloc] init];

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/grep"];
[task setArguments:arguments];
[task setStandardOutput:outPipe];
[outPipe release];

[task launch];

NSData *data = [[outPipe fileHandleForReading] readDataToEndOfFile];

[task waitUntilExit];
[task release];

NSString *string = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@""];

int linesNum = 0;

NSMutableArray *possibleMatches = [[NSMutableArray alloc] init];

if ([string length] > 0) {

    NSArray *lines = [string componentsSeparatedByString:@"\n"];
    linesNum = [lines count];

    for (int i = 0; i < [lines count]; i++) {

        NSString *currentLine = [lines objectAtIndex:i];
        NSArray *values = [currentLine componentsSeparatedByString:@"\t"];

        if ([values count] == 20)
            [possibleMatches addObject:currentLine];
    }
}
[string release];
[pool release];

return [possibleMatches autorelease];

我试图遵循 Cocoa 内存管理的一些基本规则,但不知何故似乎仍然存在泄漏,我相信这是一个正在泄漏的数组。如果 possibleMatches 很大,这很明显。您可以通过使用任何大文件作为“~/Desktop/file.txt”和表达式来尝试代码,这些文件在 grep-ing 时会产生许多结果。

我犯了什么错误?

谢谢你的帮助!

-- 瑞

编辑:我刚刚使用 Clang 静态分析器在我的代码中查找泄漏,但它没有找到任何泄漏。它只找到无效的初始化,但这些不能对我的泄漏负责......

4

2 回答 2

3

这里:

NSString *string = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@""];

您正在覆盖string对象指针而不释放或自动释放原始字符串。string不要在方法结束时释放,而是:

NSString *string = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding] autorelease];
string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@""];
于 2010-04-01T20:00:45.260 回答
0

一个可能的解决方案是使用 Instruments 的 Leaks 模板。通过将检查范围设置为在这段代码之前开始,然后查看在这段代码返回后哪些分配仍然有效,您可以看到泄漏了什么,然后查看泄漏的指针历史记录和相应的堆栈跟踪以准确查看发生了什么。

于 2010-04-03T20:54:53.977 回答