Objective-C:const char* 字符串被损坏:这是怎么回事?



我遇到一个奇怪的问题,const char字符串在初始化后被损坏。

在我的.m文件中,我有一个这样声明的指针:

const char *s;
@implementation MyClass
...
@end 

它在-init中初始化,在这一点上看起来很好:

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

后来,当我读它时,指针的地址没有改变,但值被覆盖了。

我已经把它精简到最基本的部分,并且可以确认这个字符串没有以其他方式使用,而且似乎没有任何其他可能损坏它的东西。

那么,发生了什么事?有没有我不知道的一些基本的客观性?

如有任何帮助,我们将不胜感激。

你真的没有给我们太多信息,你知道:)

无论如何,我认为这是一种糟糕的编码风格,所以我的建议如下:将s作为实例变量。真正地

这几乎是肯定的,因为C字符串的内存在某个时候会被释放。如果你绝对必须有这个全局(从你从构造函数初始化它的事实来看,这听起来可能不完全正确),那么把它设为NSString *。它将保持其值,直到明确发布为止。当需要转换为char*时,请使用cStringUsingEncoding

deobfuscatedCString在退出时是否使用自动释放对象?也许返回的地址指向当其中一个被解除锁定时被释放的内存。

如果是这种情况,并且您仍然希望schar *,请尝试:

s = strdup([@"obfuscatedString" deobfuscatedCString]);

您没有提供任何可以让我们了解发生了什么的代码,因此我们在这里无法帮助您。请提供更多详细信息。

但无论如何,即使你在问题中只写了3行代码,这已经是一种可怕的编码风格:

  • 您使用const-char*,而NSString可能更适合与其他Cocoa对象一起使用
  • 您使用了一个全局变量,这是一种非常糟糕的编码风格,可能会导致问题(比如并发访问问题等等)。请改用实例变量。真的
  • 您的变量名只有一个字符长,这是一个非常糟糕的习惯,也无助于使代码易于理解。像"S"这样的名字远非描述性的
  • 您以大写字母开头命名变量,而以大写字母开始的名称应保留给类名,实例变量应以小写字母为标准。如果这是一个常量,它可能是全大写的(而不是标题大小写),但由于变量名只有1个字母长

简而言之,请确保您阅读了编程指南,并立即养成良好的习惯(例如,如果不是绝对必要的话,避免使用char*类型的全局常量),否则会导致以后难以调试的错误(如内存损坏)。如果你想让我们帮助你解决最初的问题,请使用更多的代码。

这听起来像是其他东西在某个时刻干扰了指针或其内容。我会将常量包装在一个类方法中,并确保只从中修改它。类似这样的东西:

+ (const char *)globalCString
{
    static const char *s = NULL;
    if (!s) s = [@"obfuscatedString" deobfuscatedCString];
    return s;
}

最新更新