我隐约知道数组名称可能看起来像指针类型,但事实并非如此。
(我知道数组只是衰变为指针,而不是指针本身。如果我的理解是错误的,请告诉我(
所以我认为通过&arrayname1和&以下函数的arrayname2无法编译。
void swap(char **a, char **b)
{
char *temp;
temp = *a;
*a = *b;
*b = temp;
}
但是当我编译下面的test.c文件时,它会给我警告,但函数可以工作。
int main()
{
char a[] = "12";
char b[] = "ab";
swap(&a, &b);
// char c[] = "asdb";
printf("%s %sn", a ,b);
return (0);
}
结果如下,
ab 12
*** stack smashing detected ***: terminated
Aborted
接下来,我插入了一个无意义的语句来检查";检测到堆叠粉碎";消息可能会消失。消息消失了。
int main()
{
char a[] = "12";
char b[] = "ab";
swap(&a, &b);
char c[] = "asdb";
printf("%s %sn", a ,b);
return (0);
}
所以我的问题是。。
是否可以更改数组名称所指向的地址?
什么时候";检测到堆叠粉碎";消息出现了,这意味着什么?(我在谷歌上搜索过,但找不到消息和代码之间的关系(
为什么第二个结果没有伴随着";检测到堆栈粉碎";?
(如果有任何粗鲁的表达,请理解,因为我不擅长英语。(
如果您在标准一致模式下调用编译器,则它必须打印此错误代码的诊断消息。
许多编译器继续编译不正确的代码,除非你强迫他们不要这样做
请检查编译器文档以了解此信息。在GCC中,使用开关-pedantic
或-pedantic-errors
以及ISO一致性模式(如-std=c11
(。
不可能更改任何已存在对象的地址,数组也不例外。该代码包含约束冲突(正如您所指出的-函数参数的不兼容类型(,因此不是有效的C程序,因此编译器不必强制执行适用于有效程序的规则。因此,你可能会得到各种意想不到的行为。
- 编号。数组的放置位置(不是动态分配的(在编译时确定,在运行时不能更改
- 当检测到堆栈粉碎时,将显示此消息。在这种情况下,
swap
向传递的指针写入4字节或8字节(取决于平台,也可能是其他大小(的值,但传递的指针实际上指向3字节的数组,因此发生了对越界的写入,并调用未定义的行为 - 也许
c
的添加使a
和b
离重要数据(例如,返回地址(足够远,并防止其检测到损坏的数据