C 将字符分配到字符-意外行为

C 将字符分配到字符-意外行为,c,pointers,char,variable-assignment,C,Pointers,Char,Variable Assignment,我以为在那之后 *b = a[0] 行: 将打印字符串a中的第一个字符。以下是我的简短代码: #include <stdio.h> int main(){ char a[20]; char* b; scanf("%s", a); printf("a: %s\n", a); *b=a[0]; // I suppose something here is wrong printf("%c\n",*b); return

我以为在那之后

*b = a[0] 
行:

将打印字符串a中的第一个字符。以下是我的简短代码:

#include <stdio.h>

int main(){

    char a[20];
    char* b;

    scanf("%s", a);
    printf("a: %s\n", a);
    *b=a[0]; // I suppose something here is wrong
    printf("%c\n",*b);


    return 0;}
输出为:

a: STRING
Segmentation fault (core dumped)
据我所知,当我们试图访问未分配的内存时(静态或动态),就会出现分段错误。 这里,b是指向char的指针,它需要8个字节,因为我的操作系统是64位的。 使用*b我们取消引用指针,即访问它的内容。 b具有类型char*,a[0]具有类型char,*b具有类型char。怎么了

*b=a[0]

您发生崩溃,因为您在未初始化b时取消了对b的引用

因此,您在一个未知的地址中写入,而该地址可能无效并产生崩溃,最糟糕的情况是当可以写入时

*b=a[0]

您发生崩溃,因为您在未初始化b时取消了对b的引用


因此,您在一个未知的地址中写入,并且该地址可能无效并产生崩溃,最糟糕的情况是当可以写入时

这里的问题是您没有为
b
分配任何
char
指向,但您尝试写入
b
指向的位置,这就是它崩溃的原因

你可能想要这样的东西:

b = &a[0]
现在
b
包含
a
的第一个元素的地址,即
&a[0]
(顺便说一句,这也恰好是您通过
a
获得的相同地址)

或者,如果希望
b
指向它自己的
char
并复制代码中的第一个字符,可以事先为其分配内存:

b = malloc(sizeof(char));   // after this, *b=a[0]; can be done
如果您这样做了,请不要忘记在完成后释放内存:

free(b);

这里的问题是,您没有为
b
分配任何要指向的
char
,但是您尝试写入
b
点的位置,这就是它崩溃的原因

你可能想要这样的东西:

b = &a[0]
现在
b
包含
a
的第一个元素的地址,即
&a[0]
(顺便说一句,这也恰好是您通过
a
获得的相同地址)

或者,如果希望
b
指向它自己的
char
并复制代码中的第一个字符,可以事先为其分配内存:

b = malloc(sizeof(char));   // after this, *b=a[0]; can be done
如果您这样做了,请不要忘记在完成后释放内存:

free(b);

当然,指针本身是64位的,但它指向哪里?谁分配了这些内容?@Angew你是说,即使我为指针分配了空间(通过char*b),我也必须为b将指向的变量分配空间?就像我们调用malloc为维度为n的数组分配空间一样,我应该以某种方式为这个字符分配空间?没错。好吧,你可以让它指向已经存在的东西,但是你的
*b=a[0]行
表示“取
a
的第一个元素,复制到
b
指向的位置”。当然,指针本身是64位的,但是它指向哪里呢?谁分配了这些内容?@Angew你是说,即使我为指针分配了空间(通过char*b),我也必须为b将指向的变量分配空间?就像我们调用malloc为维度为n的数组分配空间一样,我应该以某种方式为这个字符分配空间?没错。好吧,你可以让它指向已经存在的东西,但是你的
*b=a[0]行
表示“取
a
的第一个元素,复制到
b
指向的位置”。对于这一点,它必须已经指向了有效的地方。“顺便说一句,它也恰好是
a
,这是不正确的或不精确的:编译器将数组
a
的名称衰减为指针”,这也恰好是
a[0]
的地址,顺便说一句,“谢谢你的更正,我编辑了答案。”。“顺便说一句,它也恰好是
a
”是不正确的或不精确的:编译器将数组
a
的名称衰减为指针,“它也恰好是
a[0]
的地址”,顺便说一句“感谢您的更正,我编辑了答案。