【问题标题】:Malloc to a CGPoint Pointer throwing EXC_BAD_ACCESS when accessingMalloc 到 CGPoint 指针,访问时抛出 EXC_BAD_ACCESS
【发布时间】:2010-06-17 17:06:14
【问题描述】:

我正在尝试使用 Apple 编程指南中的 sn-p 代码,并且在执行 malloc 之后尝试将指针传递给函数时得到 EXC_BAD_ACCESS。

(供参考:iPhone Application Programming Guide: Event Handling - Listing 3-6

有问题的代码很简单:

CFMutableDictionaryRef touchBeginPoints;
UITouch *touch;

....

CGPoint *point = (CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch);

if (point == NULL)
{
    point = (CGPoint *)malloc(sizeof(CGPoint));
    CFDictionarySetValue(touchBeginPoints, touch, point);
}

现在,当程序进入if 语句时,它会将malloc 的“输出”分配给point 变量/指针。

然后,当它尝试将point 传递给CFDictionarySetValue 函数时,它会导致应用程序崩溃:Program received signal: “EXC_BAD_ACCESS”.

有人建议不要使用malloc 并将point 变量/指针传递为:&point,但这仍然给了我EXC_BAD_ACCESS

我(看起来像苹果)做错了什么???

提前致谢。

【问题讨论】:

    标签: iphone c uikit core-foundation


    【解决方案1】:

    肖恩的回答大部分是正确的。根据the documentation for CFDictionarySetValue,它将根据您的CFMutableDictionaryRef 的设置方式尝试retain 的值。我猜当您创建可变字典时(大概使用CFDictionaryCreateMutable()),您没有为how to handle setting and removing values 提供自定义回调。

    编辑:

    提供自定义回调的另一个选项是为值回调提供NULL

    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
    
    CGPoint * point = (CGPoint *)malloc(sizeof(CGPoint));
    point->x = 42;
    point->y = 42;
    
    CFDictionarySetValue(dict, @"foo", point);
    
    
    CGPoint * newPoint = CFDictionaryGetValue(dict, @"foo");
    NSLog(@"%f, %f", newPoint->x, newPoint->y);
    

    日志:

    2010-06-17 11:32:47.942 EmptyFoundation[45294:a0f] 42.000000, 42.000000
    

    【讨论】:

    • 我没有做自定义回调...我使用了以下... touchBeginPoints = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    • @kdbdallas 和kCFTypeDictionaryValueCallBacks 的文档说默认的retain 回调是CFRetain,这就是你的问题所在。您必须指定自定义 retainrelease 回调(并且指定 copyequals 回调也不会有什么坏处),或者像 Dave Dribin 建议的那样,在 NSValues 中设置点。
    • 像这样定义它解决了它。 touchBeginPoints = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);谢谢!
    • 这不会泄露 malloc 的 CGPoint 吗?什么时候释放?
    • @Dave 是的,这会泄漏点和字典。我只是在编写代码以表明这是可能的。
    【解决方案2】:

    CGPoint 是一个结构体,而不是一个 Objective-C/CF 对象,所以你需要把它包装在一个NSValue

    + (NSValue *)valueWithPoint:(NSPoint)aPoint

    http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/Reference/Reference.html#//apple_ref/occ/clm/NSValue/valueWithPoint:

    【讨论】:

    • 这可以解决问题,但他在问题中链接到的列表显示CGPoint* 直接添加到字典中,而不是装箱。不幸的是,该列表也未能显示CFMutableDictionaryRef 是如何创建的。
    • 是的,很确定这个列表是完全错误的。无法将 CG/NSPoint 直接存储在 CF/NSDictionary 中。
    • @Dave Dribin 您可以将积分存储在CFDictionary 中就好了。看看我帖子中的例子。您只需要告诉字典不要尝试保留值(这很容易在 CFDictionary 创建函数中完成)。
    • 是的,只要您正确设置 CFMutableDictionary,它就可以工作。 Apple 忽略了这部分,而我创建它的方式是错误的
    • @Dave DeLong。抱歉,您对 CFDictionary 是正确的。似乎麻烦多于它的价值。我只想给我们一个NSMutableDictionaryNSValues
    【解决方案3】:

    它可能会崩溃,因为当您将 CGPoint 放入字典时,它会尝试保留您的 CGPoint,但 CGPoint 不是真实对象而是 C 结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 2017-02-25
      相关资源
      最近更新 更多