我正在尝试执行以下操作,它不会给我带来编译错误,但在运行此操作时会给我带来分段错误。
int main(){
int * ptr;
*ptr = 254;
char **ch = (char **)ptr;
printf("n%xn",**ch);
}
我基本上想知道这样的事情是否合法,如果是,它会做什么。
*(char **)ptr
其中ptr是类型int或类型void
*ptr = 254;
这里ptr
没有分配内存,这就是产生分段故障的原因。
首先需要将内存分配给ptr
,然后可以将一些值放入*ptr
。
其次,*(char **)ptr
不合法(char **ch = (char **)ptr;
、BTW也不合法)。如果你编译时启用了警告,你会得到一些警告消息
警告:从不兼容的指针类型初始化
如果你试图分析其中一个变量的数据类型,你可以很容易地理解这一点。考虑一个样本代码
#include <stdio.h>
#include <stdlib.h>
int main(){
int * ptr = malloc(4);
*ptr = 254;
char **ch = (char **)ptr;
printf("n%xn",**ch);
}
要进行检查,如果你编译并逐步通过调试器,你可以看到,
5 int * ptr = malloc(4);
(gdb) s
6 *ptr = 254;
(gdb)
7 char **ch = (char **)ptr;
(gdb) p ptr
$1 = (int *) 0x804a008
(gdb) p ch
$2 = (char **) 0xa7c600
(gdb) p *ch
$3 = 0x57e58955 <Address 0x57e58955 out of bounds>
(gdb) p **ch
Cannot access memory at address 0x57e58955
指针是一个存储地址的变量。
这里,变量ptr没有初始化为任何值。
当它试图访问ptr时,它肯定会崩溃。
因为ptr有一个垃圾地址值,而您正试图访问它。
对于给定的代码,这一定是问题所在。
但问题不在于将类型转换为char**。
在代码中很少需要设置正确的东西:
- ptr是一个指针,在你没有这样做的情况下,它应该指向某个内存位置。所以你需要分配一些内存,然后你需要访问指针
- 您正试图使用字符指针来指向整数指针。现在,这个字符指针将只有1个字节的数据可以访问,并且不会超过这个字节。(整数变量的大小可能因平台而异)
看看下面的代码:假设您使用malloc动态分配一些内存,或者使用指针指向某个位置,如下所示。
#include<stdio.h>
#include<string.h>
int main(){
int a =10;
int * ptr = &a;
*ptr = 81;/* ASCII value of Q is 81 */
printf("%dn",a);
char **ch = (char **)&ptr;/* Pointer pointing to a pointer */
printf("%cn",**ch);/* You will see Q getting printed */
/* Now if you want to modify the value of a it can be done */
**ch = 'R';
printf("%dn",a); /* The value stored in a will be 82 ASCII value of R */
printf("%cn",**ch);
printf("%dn",**ch); /* You should get 82 here */
/* Now lets say you try to set a to value 290 */
a = 290;
printf("%dn",a);/* You get 290 here */
printf("%dn",**ch); /* Sorry you won't get 290 here */
printf("%cn",**ch);
/* Since only 1 byte is what char pointer can access you get equivalent ASCII value for the value matching 8 bits */
}