在下面的示例中:
int *i;
*i=1;它会产生一个挂起的程序,因为我知道我是在将一个值直接放到内存位置。
我的问题是,为什么会出现以下情况:
int *i=1;是否仅生成与转换整数相关的警告,而不挂起程序?
为什么这条指令不会产生错误或警告?
char *s="acd";如果我使用与前面的示例类似的内容
谢谢
发布于 2012-11-21 12:22:00
让我们单独谈谈这3个案例:
int *i;
*i=1;第一行为指针分配内存,但没有初始化它,给i留下了一个随机的垃圾值。第二行试图写入由随机垃圾拼写的内存地址,导致在运行时出现未定义的行为。
int *i=1;这会为指针分配内存,并为其赋值1(即内存地址0x1)。由于这会隐式地将整数值1转换为指针,因此会收到警告,因为很少会初始化指向非空内存地址的指针。
顺便说一句,如果你要这样做:
int *i=1;
*i=1;它将尝试将值1写入内存地址0x1,导致与第一种情况相同的未定义行为。
char *s="acd";这将在堆栈上创建一个以null结尾的字符串,并使s指向该字符串。字符串文字是分配给char *的自然而然的东西,所以不会出现警告。
发布于 2012-11-21 12:20:42
您的第一种情况是唯一一种尝试写入内存的情况:
int *i; // i is a pointer but it's value is undefined
*i = 1; // Whoops, you just wrote to a random memory location.
int *i=1; // i is an invalid pointer (address 1), but you aren't writing to it
char *s="acd"; // s points to the string literal "acd" - again: no write.发布于 2012-11-21 12:23:50
int *i = 1;等同于:
int *i;
i = 1;出于同样的原因:
char *s = "acd";...is等同于:
char *s;
s = "acd";类型定义中的星号是表示i和s是指针的符号。这与在类型定义外部使用星号时不同,星号表示取消引用。
因此,在这些情况下,您只是将指针值itself...not赋值,取消对它的引用,并将其写入它所指向的内存。指针本身的内存是在堆栈上分配的,因此会被考虑在内。当您取消引用并试图在它未正确初始化时写入它时,您的危险就来了。
注意,在字符串的情况下,您可以取消对它的引用。当编译器看到字符串literal...and时,会隐式地为acd\0预留四个字符的内存,然后将文字求值为该内存的地址。所以你的s指针是好的。您的i指针是一个任意值,在大多数系统上很可能是不可读的。
https://stackoverflow.com/questions/13486244
复制相似问题