Finding EXC_BAD_ACCESS bugs in a Cocoa project

From: http://developer.apple.com/library/mac/#qa/qa1367/_index.html

 

Finding EXC_BAD_ACCESS bugs in a Cocoa project

Q:  How do I find EXC_BAD_ACCESS bugs in a Cocoa project?

A: How do I find EXC_BAD_ACCESS bugs in a Cocoa project?

This kind of problem is usually the result of over-releasing an object. It can be very confusing, since the failure tends to occur well after the mistake is made. The crash can also occur while the program is deep in framework code, often with none of your own code visible in the stack.

Summary

To avoid problems like this, you must follow the Cocoa memory management rules. Refer to ADC's document "Memory Management Programming Guide for Cocoa". The section “Object Ownership and Disposal” describes the primary policy.

Important Factors

  • If you directly allocate, copy, or retain an object, you are responsible for releasing the newly created object with release or autorelease. Any other time you receive an object, you are not responsible for releasing it.

  • A returned object is normally guaranteed to remain valid within the method it was received in (exceptions include multithreaded applications and some Distributed Objects situations). That method may also safely return the object to its invoker.

  • If you need to store a returned object in an instance variable, you must retain or copy it.

  • Use retain and autorelease when needed to prevent an object from being invalidated as a normal side-effect of a message.

  • If you instantiate an object using a convenience method, the object is already slated for autorelease. Do not send a release or an autorelease message to this object.

  • Never send a dealloc message to the object. This may dispose of the object but it does so regardless of the current reference count. Any other object that has retained the deallocated object is left with an invalid reference.

  • Never make any assumptions on how or in what order autoreleased objects are disposed.

Technical Documentation

For information on a debugging tool called NSZombieEnabled to help isolate this kind problem, as well as other debugging tips, refer to:

Technical Note 2124 Mac OS X Debugging Magic

This topic is also mentioned in the ADC Reference Library documentation:

Memory Management Rules

For an overview of Cocoa objects and their life cycles refer to the following guide:

The Life Cycle of a Cocoa Object



Document Revision History

DateNotes
2006-10-10

New document that discusses how to find memory protection violations or EXC_BAD_ACCESS bugs in Cocoa projects.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. Are there any memory errors in the following programs? If so, list all of them. Assume that the user enters in correct input, and that the sizes entered are at least one. Write your solution in a text or Word file and submit it below. void main() { char *str, *input; int *ilist; int i, size1, size2; printf("Number of letters in word: "); scanf("%d", &size1;); /* user inputs an integer */ printf("Number of integers: "); scanf("%d", &size2;); /* user inputs an integer */ str = (char *) malloc(size1); ilist = (int *) malloc(size2); printf("Word: "); scanf("%s", str); /* user inputs a string */ for(i = 0; i < size2; i++) { printf("Number %d of %d: ", i + 1, size2); scanf("%d", ilist + i); /* user inputs an integer */ } } 2. Are there any memory errors in the following program? If so, list all of them. Write your solution in a text or Word file and submit it below. /* return 1 if str is "1", 0 otherwise */ int checkIf1(char *str) { char *newstr = malloc(strlen(str) + 1); strcpy(newstr, str); /* set newstr to str */ if (strcmp(newstr, "1") == 0) { /* newstr is "1" */ return 1; } free(newstr); return 0; } void main() { char *strArr[4] = {"1", "2", "3", "4"}; int i; for(i = 0; i < 4; i++) { printf("%d\n", checkIf1(strArr[i])); } } 3. Are there any memory errors in the following program? If so, list all of them. Write your solution in a text or Word file and submit it below. struct data { char *str1, *str2; }; /* returns two strings concatenated if they are not the same, NULL otherwise */ char *mergeSingleIfDifferent(char *s1, char *s2) { char *str = (char *) malloc(strlen(s1) + strlen(s2) + 1); if (strcmp(s1, s2) == 0) { /* strings are equal */ str = NULL; } else { strcpy(str, s1); strcat(str, s2); } return str; } /* copies merged strings (or NULL) into array of strings passed in (results) */ void mergeArrayIfDifferent(char *results[], char *strA1[], char *strA2[], int size) { int i; for(i = 0; i < size; i++) { results[i] = mergeSingleIfDifferent(strA1[i], strA2[i]); } } void printAndFree(int c, char *str) { if (str != NULL) { printf("%d: %s\n", c, str); free(str); } } void main() { char *strArr1[8] = {"1", "2", "3", "4", "5", "6", "7", "8"}; char *strArr2[8] = {"a", "2", "c", "4", "e", "6", "g", "8"}; char *results[8]; int i; mergeArrayIfDifferent(results, strArr1, strArr2, 8); for(i = 0; i < 8; i++) { printAndFree(i, results); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值