0

OS X 10.8 で Xcode 4.5.1 を使用してプロジェクトを作成します。プロジェクト: アーキテクチャ: 標準 (32/64 ビット Intel) ベース SDK: OS X 10.7 展開ターゲット: 10.7

最初はすべて順調に進んでいますが、このプロジェクトを別の Macbook に Xcode 4.4.1 で OS X 10.7 にコピーすると、ランタイム エラーがスローされます。


上記の構成は変更されておらず、ファイルから構成文字列をフェッチするメソッドでエラーが発生します。

+(NSString *)configValueFromFile:(NSString *)path
               withParameter:(NSString *)parameter
{
const char *cPath = [path UTF8String];
const char *cPara = [[parameter uppercaseString] UTF8String];
char buff[CFG_CONFIG_READ_TOOL_BUFFER_LEN];
size_t paraLen = [parameter length];
size_t lineLen;
FILE *fileFd = NULL;
//struct stat dummyFileStat;
BOOL isValueFound = NO;

NSString *ret = nil;

/* open file *//*
if (0 != stat(cPath, &dummyFileStat))
{
    NSLog(@"stat() %@: %@", path, [AMCTools strError]);
    return nil;
}*/


fileFd = fopen(cPath, "r");
if(!fileFd)
{
    NSLog(@"fopen() %@: %@", path, [AMCTools strError]);
    return nil;
}

/* read configuration */
while((!feof(fileFd)) && (!isValueFound))
{
    @autoreleasepool {
        size_t tmp;

        fgets(buff, sizeof(buff), fileFd);
        if ('\0' == buff[sizeof(buff) - 1])
        {
            break;
        }

        /* get a line */
        lineLen = strlen(buff);
        if ((0 == lineLen) || ('#' == buff[0]))
        {
            continue;   /* !!!!!!! */
        }

        while(('\n' == buff[lineLen - 1]) ||
              ('\r' == buff[lineLen - 1]))
        {
            buff[lineLen - 1] = '\0';
            lineLen --;
        }

        //NSLog(@"Get line: %s", buff);

        /* upper case the parameter */
        for (tmp = 0;
             (tmp < lineLen) || ('=' != buff[tmp]);
             tmp++)
        {
            if ((buff[tmp] >= 'a') && (buff[tmp] <= 'z'))
            {
                buff[tmp] += 'A' - 'a';
            }
        }

        /* compare */
        if (0 == strncmp(cPara, buff, paraLen))
        {
            isValueFound = YES;

            /* fetch value sector */
            for (tmp = paraLen; tmp < lineLen; tmp++)
            {
                if ('=' == buff[tmp])
                {
                    tmp++;
                    break;
                }
            }   // end: for (tmp = paraLen...)

            if (tmp >= lineLen)
            {
                /* no parameter values */
                ret = @"";
            }
            else
            {
                /* skip blank */
                for (/**/; tmp < lineLen; tmp++)
                {
                    if ((' ' != buff[tmp]) &&
                        ('\t' != buff[tmp]))
                    {
                        break;
                    }
                }
                ret = [NSString stringWithUTF8String:buff+tmp];
            }
        }   // end: compare
    }   // end: autoreleasepool
}   //end: while(...)


ENDS:
    if (fileFd)
    {
        fclose(fileFd);
    }
    return ret;
}

このメソッドは、エラー " Thread 1: signal SIGABRT "をスローする "return ret" まで問題なく動作します。


私は何をすべきか?

ありがとう!!


コーディの詳細情報:

  1. あなたの懸念について:

ああ、ARC を使っていたことを忘れていました。解放されるべきではなかった。

あなたは次の行について言及しました:

const char *cPara = [[parameter uppercaseString] UTF8String];

適切でない場合、どのように修正すればよいですか?

4

1 に答える 1

0

さて、あなたの戻り値が解放されたようです。私の知る限り、stringWithUTF8String:自動解放された文字列を返します。そしてあなたの場合、それは@autoreleasepoolブロックの中にあります。そして、ブロックが終了すると ret が解放され、ゴミが返されます。

また、私はこの行について心配しています:

const char *cPara = [[parameter uppercaseString] UTF8String];

ここで cPara は一時文字列内を指します。これは、リークまたはクラッシュ (ARC の場合) である可能性があります。大文字の文字列を中間変数に格納する必要があります。

NSString uppercaseParam = [parameter uppercaseString];
const char* cPara = [uppercaseParam UTF8String];


ARC は非常に便利な機能です。

于 2013-04-11T06:37:04.553 に答える