1

I have a crash with some optimisation code. What I'm trying to do is to remove some points from the input array when the previous and the next point are close enough. The method works well in almost all case but crash with some specific data.

An example of input data that crash:

Value of coords : (51.55188, -0.17591), (51.55208, -0.17516), (51.55231, -0.17444)
Value of altitudes : 10000, 10000, 10000
Value of count : 3

If I skip the optimisation code and use directly the input value, then everything works correctly. It also works correctly if I simply memcpy the input values in the temp arrays.

I got a EXC_BAD_ACCESS EXC_I386_GPFLT after using this method with the input data posted. The crash doesn't happen directly in this method but after when I use the object created at the end of the method. I've already tried NSZombie and Profiling for zombies. Everything works correctly with almost all the data but crash 100% with this specific input data (At least it is easier for me to debug!).

The code of my method:

+ (instancetype) optimizedPolylineWithCoordinates:(CLLocationCoordinate2D*) coords altitudes:(RLMKAltitude*) altitudes count:(NSUInteger) count
{
    CGFloat minimumDistanceBetweenPoints = [self minimumOptimizedDistanceBetweenPoints];

    CLLocationCoordinate2D* tempCoords = malloc(sizeof(CLLocationCoordinate2D) * count);
    RLMKAltitude* tempAltitudes = malloc(sizeof(RLMKAltitude) * count);
    NSUInteger tempCoordsCount = 0;

    // Always keep first point
    tempCoords[0] = coords[0];
    tempAltitudes[0] = altitudes[0];
    ++tempCoordsCount;

    for (NSUInteger i = 1; i < (count - 1); i++)
    {
        MKMapPoint prevPoint = MKMapPointForCoordinate(coords[i - 1]);
        MKMapPoint nextPoint = MKMapPointForCoordinate(coords[i + 1]);

        // Get the distance between the next point and the previous point.
        CLLocationDistance distance = MKMetersBetweenMapPoints(nextPoint, prevPoint);

        // Keep the current point if the distance is greater than the minimum
        if (distance > minimumDistanceBetweenPoints)
        {
            tempCoords[tempCoordsCount] = coords[i];
            tempAltitudes[tempCoordsCount] = altitudes[i];
            ++tempCoordsCount;
        }
    }  

    // Always keep last point
    tempCoords[tempCoordsCount] = coords[(count - 1)];
    tempAltitudes[tempCoordsCount] = altitudes[(count - 1)];
    ++tempCoordsCount;

    RLMKMapWay* object =  [self polylineWithCoordinates:tempCoords altitudes:tempAltitudes count:tempCoordsCount];
    free(tempCoords);
    free(tempAltitudes);

    return object;
}

Note that the polylineWithCoordinates method called with the temp data take care of making copy of all the data so the problem is likely not related with the free located after the call (I've already tried to comment both lines and the crash still happen)

olicarbo
  • 150
  • 5
  • Which line is the crash on? – NobodyNada Mar 24 '15 at 21:55
  • I'm a little confused... Isn't `CLLocationCoordinate2D` a struct? Why are you referencing it's address space (1) and (2) how are you accessing it without the use of .`location` or `.longitude`? Additionally, getting the size of objects needs something like http://stackoverflow.com/questions/761969/checking-the-size-of-an-object-in-objective-c – Louis Tur Mar 24 '15 at 22:39
  • The CLLocationCoordinate2D pointer as input is a C style array of CLLocationCoordinate2D. Also, the use of sizeof is correct because the size of CLLocationCoordinate2D is known at compile time. – olicarbo Mar 24 '15 at 23:04

1 Answers1

0

When count == 1, you are writing outside the allocated memory.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Unfortunately the count is 3 when the crash happen... That validation is done earlier. The count will never by < 2. But you're right... I should add a check at the beginning! – olicarbo Mar 24 '15 at 22:55