Objective-C: const char * повреждена строка: что происходит? - PullRequest
1 голос
/ 06 января 2012

Я столкнулся со странной проблемой, когда строка константного символа повреждена после того, как она была инициализирована.

В моем файле .m у меня есть указатель, объявленный так:

const char *s;

@implementation MyClass
...
@end 

Он инициализирован в -init и выглядит хорошо в этот момент:

-init 
{
    if (self = [super init]) {
        s = [@"obfuscatedString" deobfuscatedCString];
    }
    return self;
}

Позже, когда я его прочитал, адрес указателя не изменился, но значение было перезаписано.

Я сократил ее до базовых элементов и могу подтвердить, что строка не используется иным образом, и, похоже, нет ничего, что могло бы ее испортить.

Итак, что происходитна?Есть ли какая-то фундаментальная цель - c, о которой я не знаю?

Любая помощь будет принята с благодарностью.

Ответы [ 5 ]

2 голосов
/ 06 января 2012

Это почти наверняка, потому что память для вашей строки C освобождается в какой-то момент.Если вам абсолютно необходимо иметь это глобальное значение (и из-за того, что вы инициализируете его из своего конструктора, похоже, что это может быть не совсем правильно), сделайте его NSString *.Он будет сохранять свое значение до тех пор, пока не будет выпущен явно.Используйте cStringUsingEncoding всякий раз, когда необходимо преобразование в char*.

2 голосов
/ 06 января 2012

Вы действительно не даете нам много информации, вы знаете:)

Я думаю, что это плохой стиль кодирования в любом случае, поэтому мой совет будет следующим: сделайте S переменной экземпляра.На самом деле.

0 голосов
/ 06 января 2012

Использует ли deobfuscatedCString объекты автоматического высвобождения при деобфускации? возможно, возвращенный адрес указывает на память, которая освобождается, когда один из них освобождается.

Если это так, и вы все еще хотите, чтобы s был char *, попробуйте:

s = strdup([@"obfuscatedString" deobfuscatedCString]);
0 голосов
/ 06 января 2012

Звучит так, будто в какой-то момент что-то еще портит указатель или его содержимое.Я бы обернул константу в методе класса и удостоверился, что изменил ее только из этого.Как то так:

+ (const char *)globalCString
{
    static const char *s = NULL;
    if (!s) s = [@"obfuscatedString" deobfuscatedCString];
    return s;
}
0 голосов
/ 06 января 2012

Вы не предоставляете никакого кода, который мог бы помочь нам понять, что происходит, поэтому мы не сможем вам здесь помочь.Пожалуйста, дайте более подробную информацию.

Но в любом случае, даже если вы написали только 3 строки кода в своем вопросе, это уже ужасный стиль кодирования:

  • Вы используете const char *, тогда какNSString, вероятно, более подходит для работы с другими объектами Какао
  • Вы используете глобальную переменную, которая является очень плохим стилем кодирования и, вероятно, приведет вас к проблемам (таким как проблемы одновременного доступа и многое другое).Вместо этого используйте переменную экземпляра.Действительно.
  • Имя вашей переменной длиной всего один символ, что является очень вредной привычкой и не помогает сделать код легко понятным.имя, подобное «S», далеко не описательное
  • Вы называете свою переменную, начинающуюся с заглавной буквы, тогда как имена, начинающиеся с заглавной буквы, должны быть зарезервированы для имен классов, а переменные экземпляра должны совпадать со строчными.Если это константа, она может быть записана в верхнем регистре (а не в заглавном регистре), но так как ваша переменная в любом случае имеет длину только 1 букву ...

Короче говоря,убедитесь, что вы читаете руководства по программированию и пользуетесь хорошими привычками прямо сейчас (например, избегаете глобальных констант типа char*, если в этом нет особой необходимости), иначе это приведет к ошибкам (таким как повреждение памяти), которые впоследствии будут трудно отлаживать.И дайте больше кода, если вы хотите, чтобы мы помогли решить вашу первоначальную проблему.

...