0

I am using a very large float array in conjunction with CIColorCube CoreImage to create filters. Since I am making many filters, the data gets repeated over and over again, and takes up to 3 minutes to compile (which is really annoying). Here's what I have:

- (void)performFilter {
    NSData * cube_data = [NSData dataWithBytes:[self colorCubeData] length:32*sizeof(float)];
    CIFilter *filter = [CIFilter filterWithName:@"CIColorCube"];
    [filter setValue:outputImage forKey:kCIInputImageKey];
    [filter setValue:@16 forKey:@"inputCubeDimension"];
    [filter setValue:cube_data forKey:@"inputCubeData"];
}

- (const void*)colorCubeData {
    float color_cube_data[32] = { 1,1,1,1,1,1,1,1.0 };
    return color_cube_data;
}

I scaled the code down A LOT. I get this error:

Address of stack memory associated with local variable 'color_cube_data' returned

I'm relatively new to c++, please help! It's probably a pretty stupid fix.

EDIT 1

Here's a snippet my actual code. Since I have multiple instances of CIColorCube that require the same format, I send each rgba channel to a selector and have it return a float array.

- (const void*)colorCubeData:(float)alpha redArray:(NSArray*)redArray blueArray:(NSArray*)blueArray greenArray:(NSArray*)greenArray {
    float r1 = [[redArray objectAtIndex:0] floatValue]/255.0f;
    float r2 = [[redArray objectAtIndex:1] floatValue]/255.0f;
    float b1 = [[blueArray objectAtIndex:0] floatValue]/255.0f;
    float b2 = [[blueArray objectAtIndex:1] floatValue]/255.0f;
    float g1 = [[greenArray objectAtIndex:0] floatValue]/255.0f;
    float g2 = [[greenArray objectAtIndex:1] floatValue]/255.0f;
    color_cube_data[16384] = { r1,g1,b1,1.0,r2,g1,b1,1.0 } 
}
iosfreak
  • 5,228
  • 11
  • 59
  • 102
  • 1
    http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – chris Apr 07 '13 at 02:47

1 Answers1

1

The problem is as the error says. You're returning the address to that array, but that array is scope-limited to that function, meaning that once the function is done, the address will no longer be safe to use (i.e. undefined behavior). You should declare float color_cube_data[32] at a higher scope (e.g. global, class, etc.) or dynamically allocate the array.

Jorge Israel Peña
  • 36,800
  • 16
  • 93
  • 123
  • Technically, it should still be valid, but if you make a function call after returning it, then the address becomes invalid. – Cole Tobin Apr 07 '13 at 02:50
  • @ColeJohnson Indeed. I suppose I'll change the wording to "no longer safe to use." – Jorge Israel Peña Apr 07 '13 at 02:50
  • 3
    It doesn't have to wait until another function call. As far as C++ is concerned, using it at all is UB. – chris Apr 07 '13 at 02:53
  • Please check my updated question. Since I will resuse float array with the same format & different variables, I wanted to use a selector and return the array to use with CIColorCube. It cleans up my code quite a bit. However, it's values get changed and it looks kinda funky. – iosfreak Apr 07 '13 at 03:07