在我的代码中找不到泄漏

发布于 2024-08-28 03:35:36 字数 1790 浏览 9 评论 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 时产生许多结果的表达式来尝试该代码。

我犯了什么错误?

感谢您的帮助!

-- Ry

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

I've been spending the last few hours trying to find the memory leak in my code. Here it is:

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];

I tried to follow the few basic rules of Cocoa memory management, but somehow there still seems to be a leak, I believe it's an array that's leaking. It's noticeable if possibleMatches is large. You can try the code by using any large file as "~/Desktop/file.txt" and as expression something that yields many results when grep-ing.

What's the mistake I'm making?

Thanks for any help!

-- Ry

EDIT: I just used the Clang Static Analyzer to find leaks in my code, but it doesn't find any. It only finds dead initializations, but those can't be responsible for my leaks...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫竹語嫣☆ 2024-09-04 03:35:36

这里:

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:@""];

Here:

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

You're overwriting the string object pointer without releasing or autoreleasing the original string. Instead of releasing string at the end of the method, do:

NSString *string = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding] autorelease];
string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@""];
别低头,皇冠会掉 2024-09-04 03:35:36

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

A probable route to a solution is to use Instruments' Leaks template. By setting the inspection range to start just before this code, then looking at which allocations are still alive after this code has returned, you can see what got leaked, and then look at the leaks' pointer histories and the corresponding stack traces to see exactly what happened.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文