指针解除引用错误的原因
Reason of error on pointer de-referencing
输出是:10
,没有错误。
int main(){
int j=10;
int *i=&j;
printf("%d",*i);
return 0;
}
但它给我一个错误:
int main(){
int *i;
int j=10;
*i=&j;
printf("%d",*i);
return 0;
}
我知道指针取消引用导致了错误。但这是怎么发生的?
i
本身 声明为 "pointer to int
"。所以你应该写 i = &j;
来给它赋值 j
.
在你的例子中,*i = &j
在赋值之前取消引用它,也就是说,一个指针的值被分配给一个int
,它驻留在合法或非法的内存块中,因为i
未初始化。
请注意,访问未初始化的变量会导致未定义的行为,更不用说访问未初始化的指针指向的对象了。
因为您使用的是未初始化的指针。
您的 *i = &j
应该是 i = &j
这将 i
定义为 int *
并将其值设置为 j
的地址:
int *i=&j;
这将i
定义为int *
,然后尝试将i
指向的地址设置为[=14=的地址]:
int *i;
int j=10;
*i=&j;
最终 *i = ...
正在尝试 取消引用 一个未初始化的变量。
int *i=&j;
在这里您声明 i
为 int *
,并分配 j
.
的地址
*i=&j;
不过,在这种情况下,您已经声明了 i
,并且您将 &j
分配给 i
指向的位置而不是 i
本身。所以这是一个错误。另一个是 i
还没有指向任何东西,因为你还没有初始化它。如果你想让 i
指向 j
,你应该删除 *
:
i = &j;
这是一个带有初始化的整数变量的简单声明 i
:
int i = 10;
通常很容易将声明和初始化分开:
int i;
/* ... */
i = 10;
没关系。但是 C 中指针声明的语法是不寻常的,并且在处理声明和初始化时会导致一点点不对称。你可以写
int *i = &j; /* correct */
但是如果你把它分开,*
就不会标记了,因为它是声明的一部分。
int *i;
/* ... */
i = &j; /* right */
*i = &j; /* WRONG */
int *i;
您已将 i
声明为指向 int
的指针,但尚未将其设置为指向 至 任何东西; i
的值是 不确定1。它将包含一些(很可能)不对应于有效地址 2 的随机位串。此时尝试取消引用 i
会导致 未定义的行为 ,这可能意味着从彻底崩溃到损坏的数据再到没有任何明显问题的工作。
行
*i = &j;
有 两个 问题,第一个是 i
没有指向任何有意义的地方(这无疑是您的运行时错误的来源;您正在尝试访问无效地址)。二是*i
和&j
的类型不匹配; *i
的类型为 int
,而 &j
的类型为 int *
。
- 不使用
static
关键字在函数局部声明的变量具有 自动存储持续时间 ,并且不会隐式初始化为任何特定值。在没有显式初始化程序的情况下,不要假设任何此类变量最初设置为 0 或 NULL
。在任何函数体之外或使用 static
关键字声明的变量具有 静态存储持续时间 ,并且这些变量将被初始化为 0 或 NULL
显式初始化程序。
- "Valid" 表示程序中定义的对象的地址(即,另一个变量,或通过 `malloc` 等分配的内存块)或平台定义的众所周知的地址(例如固定的硬件输入地址)。
NULL
是一个明确定义的 无效 地址,易于测试。
输出是:10
,没有错误。
int main(){
int j=10;
int *i=&j;
printf("%d",*i);
return 0;
}
但它给我一个错误:
int main(){
int *i;
int j=10;
*i=&j;
printf("%d",*i);
return 0;
}
我知道指针取消引用导致了错误。但这是怎么发生的?
i
本身 声明为 "pointer to int
"。所以你应该写 i = &j;
来给它赋值 j
.
在你的例子中,*i = &j
在赋值之前取消引用它,也就是说,一个指针的值被分配给一个int
,它驻留在合法或非法的内存块中,因为i
未初始化。
请注意,访问未初始化的变量会导致未定义的行为,更不用说访问未初始化的指针指向的对象了。
因为您使用的是未初始化的指针。
您的 *i = &j
应该是 i = &j
这将 i
定义为 int *
并将其值设置为 j
的地址:
int *i=&j;
这将i
定义为int *
,然后尝试将i
指向的地址设置为[=14=的地址]:
int *i;
int j=10;
*i=&j;
最终 *i = ...
正在尝试 取消引用 一个未初始化的变量。
int *i=&j;
在这里您声明 i
为 int *
,并分配 j
.
*i=&j;
不过,在这种情况下,您已经声明了 i
,并且您将 &j
分配给 i
指向的位置而不是 i
本身。所以这是一个错误。另一个是 i
还没有指向任何东西,因为你还没有初始化它。如果你想让 i
指向 j
,你应该删除 *
:
i = &j;
这是一个带有初始化的整数变量的简单声明 i
:
int i = 10;
通常很容易将声明和初始化分开:
int i;
/* ... */
i = 10;
没关系。但是 C 中指针声明的语法是不寻常的,并且在处理声明和初始化时会导致一点点不对称。你可以写
int *i = &j; /* correct */
但是如果你把它分开,*
就不会标记了,因为它是声明的一部分。
int *i;
/* ... */
i = &j; /* right */
*i = &j; /* WRONG */
int *i;
您已将 i
声明为指向 int
的指针,但尚未将其设置为指向 至 任何东西; i
的值是 不确定1。它将包含一些(很可能)不对应于有效地址 2 的随机位串。此时尝试取消引用 i
会导致 未定义的行为 ,这可能意味着从彻底崩溃到损坏的数据再到没有任何明显问题的工作。
行
*i = &j;
有 两个 问题,第一个是 i
没有指向任何有意义的地方(这无疑是您的运行时错误的来源;您正在尝试访问无效地址)。二是*i
和&j
的类型不匹配; *i
的类型为 int
,而 &j
的类型为 int *
。
- 不使用
static
关键字在函数局部声明的变量具有 自动存储持续时间 ,并且不会隐式初始化为任何特定值。在没有显式初始化程序的情况下,不要假设任何此类变量最初设置为 0 或NULL
。在任何函数体之外或使用static
关键字声明的变量具有 静态存储持续时间 ,并且这些变量将被初始化为 0 或NULL
显式初始化程序。 - "Valid" 表示程序中定义的对象的地址(即,另一个变量,或通过 `malloc` 等分配的内存块)或平台定义的众所周知的地址(例如固定的硬件输入地址)。
NULL
是一个明确定义的 无效 地址,易于测试。