2

I have a function which converts my array into string when i run this function for an array of 50000 length, my app crashes and message says terminate due to memory error. Here is my function given below.

-(NSString*)getStringFromArray:(NSMutableArray*)array
{
    NSString* resultantString = [array objectAtIndex:0];
    for (int i = 1; i < [array count]; i ++)
    {
        resultantString = [NSString stringWithFormat:@"%@ %@", resultantString, [array objectAtIndex:i]];
    }
    return resultantString;
}
Usman Javed
  • 2,437
  • 1
  • 17
  • 26

5 Answers5

0

You can try to use a NSMutableString instead multiples NSString, so at end convert to NSString

Something like that:

-(NSString*)getStringFromArray:(NSMutableArray*)array
{
    //NSString* resultantString = [array objectAtIndex:0];
    NSMutableString * buffer = [[NSMutableString alloc] init];
    for (int i = 0; i < [array count]; i ++)
    {
        //resultantString = [NSString stringWithFormat:@"%@ %@", resultantString, [array objectAtIndex:i]];
        [buffer appendString:[array objectAtIndex:i]];
    }

    NSString *resultantString = [[buffer copy] autorelease];
    return resultantString;
}

The code wasn't checked,because i'm not in a mac to do that, but that is the idea

I hope this helps

Community
  • 1
  • 1
Icaro Martins
  • 307
  • 12
  • 22
  • Replacing `NSString` with `NSMutableString` only does not help much. He should use the `appendString` method or `appendFormat` of `NSMutableString` instead of `stringWithSomething`. – Hermann Klecker Jan 22 '15 at 13:27
  • is that what i'm talk about `You can try to use NSMutableString instead multiples NSString`, and i posted the links with explanations @HermannKlecker – Icaro Martins Jan 22 '15 at 14:56
0

Check how many characters your string will have at the end : NSString can hold a little over 4.2 billion characters.

Your are possibly trying to create a NSString over the character limit.

Quick calculation : around 85 characters to each entry in your array.

Niko
  • 3,412
  • 26
  • 35
0

There isn't enough time for the memory you are using to be released in such a large loop.

You can use an autorelease pool:

@autoreleasepool {
           resultantString = [NSString stringWithFormat:@"%@ %@", resultantString, [array objectAtIndex:i]];
}

or use a different tactic:

resultantString = [resultantString stringByAppendingString:[array objectAtIndex:i]];

This will cause a crash and a huge memory spike: Further to the comments:

NSString* sourceString = @"";
for (int i = 1; i < 50000; i ++)
{
    sourceString = [NSString stringWithFormat:@"%@ %@", sourceString, @"foo"];

}

This will not:

NSString* sourceString = @"";
for (int i = 1; i < 50000; i ++)
{
    sourceString = [sourceString stringByAppendingString:@"foo"];
}
davbryn
  • 7,156
  • 2
  • 24
  • 47
  • Using @autoreleasepool should help, accoriding to the documentation. But for reasons that I don't know ofthen it does not help very much. However, changing to any `stringByOrWithSomething` method does not make much of a change! Every method starting with string does create an new autoreleased instance of NSSring. – Hermann Klecker Jan 22 '15 at 13:29
  • @HermannKlecker Incorrect on both counts: Autorelease will free up the memory as long as it is within the loop and nothing else is holding a reference. I've expanded in the answer as my code messed up here – davbryn Jan 22 '15 at 13:50
0

You are creating 50,000 autoreleased strings of enormous lengths. So what do you expect? You are abusing what autorelease is there for.

Replacing [NSString stringWithFormat:...] with [[NSString alloc] initWithFormat...] will help a lot. If you don't understand what the difference is then you really need to go back to basics and understand what autorelease means.

Obviously this is still awfully inefficient. Much much much much better to use an NSMutableString. And even better to use the built-in method of NSArray componentsJoinedByString.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • I agree with your first part, but I seriously doubt if there is any difference at all between `stringWithFormat` and `initWithFormat`. – Hot Licks Jan 22 '15 at 13:32
  • stringWithFormat returns an autoreleased object. [[NSString alloc] initWithFormat] returns an object with a reference count of 1, which will be removed by ARC at the earliest possible time. There will be only one object in memory at a time, not up to 50,000. – gnasher729 Jan 22 '15 at 16:27
0

Am I missing something? (It's not a great question.) Are you simply trying to concatenate the elements of an array?

Foundation has a method to do exactly that:

-(NSString*)getStringFromArray:(NSMutableArray*)array {
    return [array componentsJoinedByString:@" "];
}
Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152