Objective-C标题中的C指针损坏

时间:2011-11-18 03:58:31

标签: objective-c c arrays pointers header

我的标头中有一个CGFloat指针,用于指向CGFloat数组。我这样声明:CGFloat* pointer;。在初始化中,我尝试使用以下代码设置指针:

CGFloat newArray[2] = {
            0.0f, 1.0f,
        };

        pointer = newArray;

这“实际”有效。我没有得到任何编译器错误和东西。当我使用以下代码设置指针后立即打印数组的第二个值:printf("%f", pointer[1]); 我得到了正确的结果(1.000000)。但是,当我在名为next的方法中打印数组的第二个值时,我得到0.000000,这意味着指针不再指向数组。

我有两个问题。我如何解决这个问题以及为什么指针在设置之后才能正常工作但是再次“忘记”它的值?

4 个答案:

答案 0 :(得分:1)

CGFloat newArray[2] = {
        0.0f, 1.0f,
    };

数组索引从0开始。pointer[1]打印数组中的 second 元素,而不是第一个。 pointer[2]不在数组的末尾。

CGFloat newArray[2] = {0,0};
newArray[0]; // this is the 1st item
newArray[1]; // this is the 2nd item
newArray[2]; // this is nonsense.

请注意,如果您尝试在某个地方传递newArray以便稍后使用它,那将是不好的。 newArray位于堆栈中,当范围被销毁时将被销毁。

如果你想要一个返回两个浮点数组的函数,你可以这样做:

 CGFloat *two_of_these() {
     CGFloat *newArray = malloc(2 * sizeof(CGFLoat));
     newArray[0] = 42.0;
     newArray[1] = 59.4;
     return newArray;
 }

请确保稍后在该返回值上调用free。请注意,分配这么小的东西是非常罕见的。通常,它将是直接返回的结构。请参阅CGPointCGRectNSRange等等。

答案 1 :(得分:1)

Larcus,newArray正在非全局范围内的堆栈上初始化。阵列的内存分配在一个特定的范围内。当您调用其他方法时,CGFloat* pointer不再指向newArray,因为newArray此时可能存在,也可能不存在。如果未从第一个范围内调用第二个方法,则严格newArray将从其原始堆栈帧中解除分配。而是分配像pointer = new CGFloat[2]; pointer[0] = 0.0; pointer[1] = 1.0;

这样的指针

我认为这是保证您分配的内存将在堆上分配而不是随机覆盖或取消范围的唯一方法。

请参阅Dangling Pointers

上的维基百科

如果您不使用mallocnew分配内存并将该内存分配给指针,那么该内存的状态将是未定义的。只有mallocnew才能以永久保留在应用程序所有范围内的方式初始化内存。

答案 2 :(得分:0)

我认为你从bbum的回答得到数组索引。 '指针'指向一个地址。您将其设置为newArray的地址,但是当调用第二个方法时,不保证newArray可以使用。

答案 3 :(得分:0)

一般来说,newArray的{​​{3}}似乎比pointer短,因此指针在第二次调用时变为无效。要解决此问题,您需要移动初始化var,因此它将具有与pointer相同的生命周期。另一个解决方案是在运行时分配内存(使用malloc等),并在使用后释放它。