Ошибка EXC_BAD_ACCESS при использовании NSString getCString - PullRequest
2 голосов
/ 06 февраля 2012

Я пытаюсь разобрать какой-то HTML.Я использую stringWithContentsOfURL, чтобы получить HTML.Я пытаюсь загрузить это в массив символов, чтобы я мог его проанализировать, но я получаю сбой с ошибкой EXC_BAD_ACCESS, когда вызывается getCString.Вот соответствующий код:

- (void)parseStoryWithURL:(NSURL *)storyURL
{
    _paragraphs = [[NSMutableArray alloc] initWithCapacity:10];
    _read = NO;

    NSError* error = nil;
    NSString* originalFeed = [NSString stringWithContentsOfURL:storyURL encoding:NSUTF8StringEncoding error:&error];

    _i = originalFeed.length;
   char* entireFeed = malloc(_i*sizeof(char));
   char* current = entireFeed;
   char* lagger;
   char* recentChars = malloc(7);
   BOOL collectRecent = NO;
   BOOL paragraphStarted = NO;
   BOOL paragraphEnded = NO;
   int recentIndex = 0;
   int paragraphSize = 0;

   NSLog(@"original Feed: %@", originalFeed);


   _read = [originalFeed getCString:*entireFeed maxLength:_i encoding:NSUTF8StringEncoding];

Я также пытался передать указатель 'current' в getCString, но он ведет себя так же.Из того, что я прочитал, эта ошибка обычно выдается при попытке чтения из освобожденной памяти.Я программирую для iOS 5 с управлением памятью.Строка до этого я печатаю HTML в лог и все нормально.Помощь будет оценена.Мне нужно обойти эту ошибку, чтобы я мог проверить / отладить свои алгоритмы разбора HTML.

PS: Если кому-то достаточно репутации разрешено, добавьте "getCString" в качестве тега.Видимо никто не использует эту функцию: (

Ответы [ 3 ]

1 голос
/ 06 февраля 2012

Попробуйте явно использовать malloc'ing entireFeed с длиной _i (в этом нет уверенности на 100%, поскольку NSUTF8String может также включать двухбайтовые unichars или wchars) вместо дурацкого char * entireFeed[_i], который вы делаете.

Я не могу себе представить, char * entireFeed[_i] работает во время выполнения (и вместо этого вы передаете NULL-указатель на ваш метод getCString).

1 голос
/ 06 февраля 2012

Есть несколько проблем с вашим кодом - вы пропускаете неправильные указатели и не резервируете достаточно места.Вероятно, проще всего использовать вместо него UTF8String:

char *entireFeed = strdup([originalFeed UTF8String]);

В конце вам все же придется освободить строку с помощью free(entireFeed).Если вы не измените его, вы можете использовать

const char *entireFeed = [originalFeed UTF8String];

напрямую.

Если вы хотите использовать getCString, сначала вам нужно будет определить длину, которая должнасимвол завершения, а также дополнительный пробел для закодированных символов, например что-то вроде:

NSUInteger len = [originalFeed lengthOfBytesUsingEncoding: NSUTF8StringEncoding] + 1;
char entireFeed[len];
[originalFeed getCString:entireFeed maxLength:len encoding:NSUTF8StringEncoding];
1 голос
/ 06 февраля 2012

Несколько странных вещей;

char* entireFeed[_i]; выделяет массив char *, а не массив char. Я подозреваю, что вы хотите char entireFeed[_i] или char *entireFeed = malloc(_i*sizeof(char));

getCString принимает символ * в качестве первого параметра, то есть вы должны отправить его entireFeed вместо *entireFeed.

Также обратите внимание, что кодировка (UTF-8) может добавить байты к результату, поэтому при выделении буфера точного размера входных данных метод может вернуть NO (слишком маленький буфер). Вы должны действительно использовать [originalFeed UTF8String] вместо этого.

...