EXC_BAD_ACCESS尝试重写NSString ComponentsSeparatedByString:

时间:2012-09-25 11:15:21

标签: objective-c arrays nsstring char

我正在编写一个Objective-C程序,用XCODE 4.3.1和ARC处理生物分子的轨迹。我需要读取PDB文件,即解析大量文本格式的数据。我对NSString的低效率感到非常失望,并且正在尝试编写一个C-equivalent of componentsSeparatedByString:。该算法适用于NSString和NSMutableArrays,但我很难使用char *和char **。

不幸的是,我收到了EXC_BAD_ACCESS错误。奇怪的是,我得到i = 68103和j = 68049的错误(这些数字是否响铃?),这意味着它在崩溃前工作了一段时间。错误是“静态的”(总是在相同的(i,j)数字处阻塞)。该数组似乎工作正常(崩溃前NSLog值)。

看起来,我对C代码和指针背后的细微之处并不十分熟悉,但我很高兴听到你的建议让它成功!谢谢!

下面是代码:

+(char**) componentsSeparedByNewLineCEQUIV:(const char*)aChar:(int*)numWord
{ // char* aChar : my file, is typically 3 millions characters
int j=-1; //Last non space character
int i; //Scanned character
int len=strlen(aChar);

char** stringArray=malloc((*numWord)*sizeof(char*));

for (i=0;i<len; i++)
{   if (aChar[i]==10)
    {
        if ( j!=-1)
        {   
            char* buffer2=malloc(i-j+1);
            strcpy(buffer2, strndup(aChar+j, i-j));
            stringArray[i]=malloc(sizeof(char)*strlen(buffer2)+1); //EXC_BAD_ACCESS HERE
            strcpy(stringArray[i], buffer2);
        }
        j=-1;
    }
    else if (j==-1)
    {j=i;}
}
if (j!=-1)
{   char* buffer2=malloc(i-j+1);
    strcpy(buffer2, strndup(aChar+j, i-j));
    stringArray[i]=malloc(strlen(buffer2)+1);
    strcpy(stringArray[i], buffer2);
}

return stringArray;
}

4 个答案:

答案 0 :(得分:0)

你可能不是第一个遇到这个问题的人:)

为什么不使用strtok

PS什么分析表明NSString是你的问题?

答案 1 :(得分:0)

我不知道为什么错误出现在它应该的位置。但是你要复制一个未分配的字符串。
当你在buffer2上复制时,不分配stringArray [i],分配它:

    if ( j!=-1)
    {   
        char* buffer2=malloc(i-j+1);
        strcpy(buffer2, strndup(aChar+j, i-j));
        stringArray[i]=malloc(sizeof(char)*strlen(buffer2)+1); //EXC_BAD_ACCESS HERE
        stringArray[i]=(char*)malloc( (strlen(buffer2)+1)*sizeof(char));  // Allocate the string
        strcpy(stringArray[i], buffer2);
    }

答案 2 :(得分:0)

首先:如果我不是完全错误的,但我认为你消耗的内存至少是你需要的4倍:

您正在使用malloc创建buffer2,并使用strndup来获取想要的字符。 strndup完全符合您的要求,但只需一步即可。 char* buffer2 = strndup(aChar+j, i-j)应该是你迈出的第一步。更糟糕的是,在接下来的两行中,你必须再次做同样的事情。所以我认为你真正想要的是stringArray[i] = strndup(aChar+j, i-j)。查看内存问题:所有函数都使用errno来指示内存分配失败。

第二:你的函数没有返回组件的数量,所以你的stringArray可能包含一些垃圾而不知道。

第三:strlen价格昂贵且您不需要它,只需使用for(int i = 0; aChar[i] != '\0'; i++)

答案 3 :(得分:0)

可能感兴趣的每个人的更新:这是一个工作版本,使用strtok可能很有用,虽然我仍然对我的代码的响应感兴趣。

此代码的测试速度比[astring componentsSeparatedByString:@“\ n”]快5倍(125ms vs 581ms)......

+(char**)componentsSeparatedByNewLine:(const char*)aChar:(int*)numWord
{

int i;
int j=0;
int len = strlen(aChar);
*numWord=1;
for (i=0;i<len; i++)
{
    if (aChar[i]==10) *numWord=*numWord+1;   //change 10 for any other character (ASCII for space)
}

char** stringArray=malloc((*numWord)*sizeof(char*));
char* pch;

char* aChar2=malloc(len+1);
strcpy(aChar2,aChar);

pch = strtok(aChar2,"\n");
while (pch != NULL)
{   
    stringArray[j]=(char*)malloc( (strlen(pch)+1)*sizeof(char));
    strcpy(stringArray[j], pch);
    //NSLog(@"%s",stringArray[j]);
    j=j+1;
    pch = strtok (NULL, "\n");
}
return stringArray;
}