我在 C 中尝试了这种方法,因为我不想预定义 char* 的大小(如 char[999]),我的主要目的是创建一个 char* 变量来保存特定的单词(我不知道它是如何运行的)当我使用这段代码时(我也不相信它会在我编码时正常工作),它会为一个字符创建一个内存空间。但是当我尝试打印时,它会打印整个字符串,令人惊讶的是,当我调试它时控制台只显示字符串的第一个字符
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node
{
int val;
char* name;
struct Node* next;
};
int main()
{
struct Node* list;
list=(struct Node*) malloc(sizeof(struct Node));
list->name=(char*) malloc(sizeof(char));
printf("Enter a string");
scanf("%s",list->name);
printf("%s",list->name);
return 0;
}
我认为存在内存泄漏或其他问题。因为 malloc() 函数中没有任何乘数,我不相信编译器会分配足够的内存,但我不知道它如何保存第一个我不知道在哪里的字母之后。
当您使用 malloc(sizeof(char)) 为 name 分配内存时,您正好分配了一个字节的内存,这足以容纳一个字符。在 C 中,字符串以 null 结尾,这意味着它们以特殊的 null 字符 (' ') 结尾。因此,从技术上讲,这个分配只有空字符串的空间(只是空终止符)。
当您使用 scanf("%s", list->name) 从用户读取字符串时,scanf 并不知道您只为一个字符分配了空间。它将继续将用户的输入写入从 list->name 开始的内存中,如果用户输入多个字符,则可能会超出分配的空间。这称为缓冲区溢出,是 C 程序中错误和安全漏洞的常见来源。
尽管存在缓冲区溢出,您可能会发现您的程序对于小字符串似乎可以正常工作。这是因为写入超过分配的内存可能不会立即导致崩溃;它会覆盖程序内存的其他部分,这些部分可能不会立即使用或检查。然而,这是不可预测且不安全的。该行为可能会随着不同的输入、编译器优化甚至同一程序的不同运行而改变。
如前所述:“因为我不想预定义 char* 的大小(如 char[999]),我的主要目的是创建一个 char* 变量来保存特定单词”
也许你可以这样写:
char buffer[999];
int main()
{
scanf("%s", buffer);
int len = strlen(buffer);
printf("%d", strlen(buffer));
struct Node* list;
list = (struct Node*)malloc(sizeof(struct Node));
list->name = (char*)malloc((len + 1) * sizeof(char));
strcpy(list->name, buffer);
printf("%s", list->name);
return 0;
}
我认为不可能提前预测用户会输入多少个字符......