for循环耗尽内存

时间:2013-05-17 15:17:08

标签: objective-c memory

嘿所以我认为如果我制作一个随机密码的小应用程序然后让应用程序运行所有可能性并尝试查看密码告诉我它尝试了多少次会很酷。有时应用程序有效,崩溃取决于密码是什么。我想知道我有什么办法可以通过占用大量内存来阻止它崩溃。这是方法。

-(void)hackString 
 {
    NSString *string;
    NSString *string1;
    NSString *string2;
    NSString *string3;
    NSString *string4;
    NSString *string5;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){


    NSString *hackedString;

    for (string in self.validLetters) {
    //[hackedString appendString:string];
        for (string1 in self.validLetters) {
            //[hackedString appendString:string1];
            for (string2 in self.validLetters) {
                //[hackedString appendString:string1];
                for (string3 in self.validLetters) {
                    //[hackedString appendString:string1];
                    for (string4 in self.validLetters) {
                        for (string5 in self.validLetters) {
                             hackedString = [NSString stringWithFormat:@"%@%@%@%@%@%@",string,string1,string2,string3,string4,string5];
                           // NSLog(@"%@",hackedString);
                            [self testStringWithPassword:hackedString];

                        }

                    }
                }
            }
        }
    }
         });

} 

我应该做些什么来阻止它崩溃?

3 个答案:

答案 0 :(得分:4)

如果您的应用程序内存不足,很可能是因为您正在使用大量对象填充自动释放池,以达到内存耗尽的程度。

天真地,您可以在其中一个内部@autoreleasepool{}循环周围使用for()

但是,大多数密码输入系统会立即将密码散列为一些不可反向转换的字符串,然后将其与存储的散列进行比较。因此,您的方法不太可能对测试密码有用。您可能需要实现相同的散列。

我曾经在我公司的用户密码数据库上运行密码破解程序(有点像 John the Ripper ),向密码较弱的人发送自动发送电子邮件。我们最终解雇了一个人,因为他们无法在几分钟内考虑到破解者无法打败的密码(还有其他原因,性质相似)。

答案 1 :(得分:1)

  

我应该做些什么来阻止它崩溃?

你确定程序崩溃了吗?如果您的程序真的崩溃了,您应该收到崩溃日志或控制台消息,告诉您崩溃的位置,并且您应该能够看到它在调试器中崩溃的位置。

您的程序可能需要花费很长时间才能运行,因为您要求它生成来自validLetters的六个字符串的每个组合。根据具体情况,您的程序也可能被操作系统中的监视程序进程杀死。

另一方面,您的程序可能会崩溃,因为它的内存不足。每次调用-stringWithFormat:时都会分配内存,这会创建一个新的自动释放字符串。由于您永远不会让运行循环运行,因此自动释放池永远不会耗尽。如果你的程序花了太长时间才能找到它正在寻找的字符串,你可能很容易耗尽所有可用内存。所以,首先,尝试将最里面的for循环放在@autorelease块中,例如:

@autorelease {
    for (string5 in self.validLetters) {
        hackedString = [NSString     stringWithFormat:@"%@%@%@%@%@%@",string,string1,string2,string3,string4,string5];
                           // NSLog(@"%@",hackedString);
        [self testStringWithPassword:hackedString];

    }
}

答案 2 :(得分:0)

stringWithFormat:返回一个自动释放的字符串。这意味着它不会被清理,直到该方法调用返回(并且自动释放池耗尽),因此内存不足。如果您不使用ARC,则可以显式初始化并释放字符串:

hackedString = [[NSString alloc] initWithFormat:@"%@%@%@%@%@%@",string,string1,string2,string3,string4,string5]];
[self testStringWithPassword:hackedString];
[hackedString release];

如果您使用ARC,请在其中一个内部循环周围添加@autoreleasepool,我建议使用string4循环。