我从堆中分配内存来存储一个字符,但它包含一个字符串 #包括 #包括 int main() { 字符*名称; name=(char*)malloc(sizeof(char)); printf(“输入名称:”); scanf(“%s”,名称); printf(“%s”,名称); 返回0; }

我从堆中分配内存来存储一个字符,但它包含一个字符串 #包括 #包括 int main() { 字符*名称; name=(char*)malloc(sizeof(char)); printf(“输入名称:”); scanf(“%s”,名称); printf(“%s”,名称); 返回0; },c,string,character,heap-memory,allocation,C,String,Character,Heap Memory,Allocation,当我只为单个字符分配内存时,上面的代码完美地存储了整个字符串。这怎么可能 您只为一个字符分配了内存,该字符足以存储终止的空字节。你需要分配更多 例如: #include<stdio.h> #include<stdlib.h> int main() { char* name; name=(char* )malloc(sizeof(char)); printf("Enter a name: "); scanf("%s",name);

当我只为单个字符分配内存时,上面的代码完美地存储了整个字符串。这怎么可能

您只为一个字符分配了内存,该字符足以存储终止的空字节。你需要分配更多

例如:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char* name;
    name=(char* )malloc(sizeof(char)); 
    printf("Enter a name: ");
    scanf("%s",name);
    printf("%s",name);
    return 0;
}
请注意。相反,我更喜欢。还要注意的是,如果有需要删除的空间,则
fgets()
将读取换行符


另请参见:

您只为一个字符分配了内存,这足以存储终止的空字节。你需要分配更多

例如:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char* name;
    name=(char* )malloc(sizeof(char)); 
    printf("Enter a name: ");
    scanf("%s",name);
    printf("%s",name);
    return 0;
}
请注意。相反,我更喜欢。还要注意的是,如果有需要删除的空间,则
fgets()
将读取换行符

另请参见:

您有。非常好。阅读

name
是一个真正的字符串(即以零字节结尾的合法有效内存区域)时,这一点就起作用了。在您的程序中,它不是,您正在访问超过
malloc
-ed区域的至少一个字节。你有一个好主意

当单个字符区域是有效字符串时,它的唯一情况是该单个
char
包含零字节,因此该字符串为空

上面的代码完美地存储了整个字符串

你只是运气不好(顺便说一句,它不是“完美的”)。它可能更糟(例如宇宙崩溃),也可能更好(例如一些…)。这就是为什么你应该害怕UB

(为了解释在您的特定计算机上发生的情况,您需要深入了解实现细节,例如,研究您的操作系统、编译器、指令集、编译器生成的汇编代码等;您不想在这方面花费数年的时间,即使您这样做了,也不想浪费时间)

您应该使用所有警告和调试信息(
gcc-Wall-Wextra-g
)进行编译,并使用调试器
gdb
,并确保程序处理的每个内存位置都有效

顺便说一句,
malloc
可能会失败,您应该对此进行测试,
sizeof(char)
定义为1。你应该试试

printf("%s",name);
请阅读您正在使用的每个功能的文档。从和开始。请注意,使用
scanf
是危险的。最好用
\n
结束
printf
控制字符串,或者适当使用(因为stdout通常是行缓冲的)。还可以下载并学习编程语言的规范

在某些系统上,您拥有比C11标准所保证的更多的功能。例如,POSIX有
getline
,您可以像这样使用它。还可以考虑(在C11标准中)如果你没有POSIX系统(那么你需要复杂的技巧来读取任意的长行,或者指定和记录你的程序只处理最多79字节的行,如果使用<代码> MalOC(80)< /C> >。 这是一种很好的礼貌,在你的代码;当然,您的计算机仍然有局限性(您可能无法处理1000亿字节的行)

注意(另见)。请在2017年的今天使用(例如,使用of或of),但请记住,一个字符可以跨越多个字节(即
char
-s)。

您有。非常好。阅读

name
是一个真正的字符串(即以零字节结尾的合法有效内存区域)时,这一点就起作用了。在您的程序中,它不是,您正在访问超过
malloc
-ed区域的至少一个字节。你有一个好主意

当单个字符区域是有效字符串时,它的唯一情况是该单个
char
包含零字节,因此该字符串为空

上面的代码完美地存储了整个字符串

你只是运气不好(顺便说一句,它不是“完美的”)。它可能更糟(例如宇宙崩溃),也可能更好(例如一些…)。这就是为什么你应该害怕UB

(为了解释在您的特定计算机上发生的情况,您需要深入了解实现细节,例如,研究您的操作系统、编译器、指令集、编译器生成的汇编代码等;您不想在这方面花费数年的时间,即使您这样做了,也不想浪费时间)

您应该使用所有警告和调试信息(
gcc-Wall-Wextra-g
)进行编译,并使用调试器
gdb
,并确保程序处理的每个内存位置都有效

顺便说一句,
malloc
可能会失败,您应该对此进行测试,
sizeof(char)
定义为1。你应该试试

printf("%s",name);
请阅读您正在使用的每个功能的文档。从和开始。请注意,使用
scanf
是危险的。最好用
\n
结束
printf
控制字符串,或者适当使用(因为stdout通常是行缓冲的)。还可以下载并学习编程语言的规范

在某些系统上,您拥有比C11标准所保证的更多的功能。例如,POSIX有
getline
,您可以像这样使用它。还可以考虑(在C11标准中)如果你没有POSIX系统(那么你需要复杂的技巧来读取任意的长行,或者指定和记录你的程序只处理最多79字节的行,如果使用<代码> MalOC(80)< /C> >。 这是一种很好的礼貌,在你的代码;当然,您的计算机仍然有局限性(您可能无法处理1000亿字节的行)

注意(另见)。请在2017年的今天使用(例如,使用of或of),但请记住,一个字符可以跨越多个字符