我正在学习弦乐,在我上一次练习中发生了一些奇怪的事情:
char cadena5[]="Mensaje: ";
char cadena6[50]="Mensaje: "; //reserva espacio extra en memoria
char cadena7[]="Programar en Objective C es facil";
NSLog(@"La logitud de cadena5 es: %li", strlen(cadena5) );
NSLog(@"La logitud de cadena6 es: %li", strlen(cadena6) );
NSLog(@"La logitud de cadena7 es: %li", strlen(cadena7) );
strcat(cadena5, cadena7);
NSLog(@"strcat %s", cadena5);
我的输出显示了附加的完整字符串,但在我的书中说xcode会抱怨因为没有足够的可用空间来附加" cadena5"并建议使用" cadena6"代替。
2014-05-16 23:43:02.518 Array de chars[3027:303] La logitud de cadena5 es: 9
2014-05-16 23:43:02.518 Array de chars[3027:303] La logitud de cadena6 es: 9
2014-05-16 23:43:02.519 Array de chars[3027:303] La logitud de cadena7 es: 33
2014-05-16 23:43:02.520 Array de chars[3027:303] strcat Mensaje: Programar en Objective C es facil
看教程应该出现一个"信号SIGABRT"线... 发生了什么?这是正常的吗?
答案 0 :(得分:2)
根据所有权利,该计划应该得到一个SEGFALT,更糟糕的是。但它很幸运,并且需要记忆。
在更一般的情况下,它可能经历过"无法解释的"对其他变量的更改 - 如果在内存中的正确位置有很多其他变量。
您可以通过一个非常小的改变使这个程序可移植和正确地工作:
char cad1[100] = "Hola ";
这会过度分配目标字符串,并允许附加有限数量的文本。
答案 1 :(得分:-1)
变量按照它们在函数中出现的顺序被压入堆栈。当某些东西被推送时,堆栈指针会减少所需的内存量,然后将对象写入该位置。
如果你的程序没有崩溃,你可能在cadena5
之前定义了变量。如果你有
char A[10];
char B[10];
你可以安全地"将20个字符写入B
,不适合B
的10个字符是"只是"覆盖A
。
这已经很糟糕了,但情况变得更糟:在某些时候你会覆盖返回地址,并且当崩溃变得不可避免时就会这样。
因此,如果您想要崩溃,只需删除cadena5
之前的任何变量定义。
编辑:这适用于C,我不知道它在Objective-C中的含义。
Edit2:这不保证,编译器可以自由地按堆栈的任何顺序排列变量,请参阅注释。