Bri*_*446 0 c arrays string pointers memory-management
使用指针时为什么不需要指定数组大小?
我是C的新手,并试图更好地了解它是如何工作的.
如果我使用指针来声明数组问候,我不需要指定数组大小.如果我拿走指针,那么我需要定义数组的大小.
为什么编译器在使用指针声明char变量时不需要知道要分配的数组的大小,但是当我只声明一个char变量时它就会这样做.有点混淆为什么会这样.
这是我的示例代码:
int main()
{
char *greet; // Works fine.
// char greet; // Doesn't work. Crashes when entering text.
// char greet[]; // Doesn't work. Array size missing, won't compile.
// char greet[20]; // Works fine.
printf("Enter name\n>");
gets(greet);
printf("Hello %s", greet);
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常,实际上,它是未定义的行为.
对于任何未初始化的自动存储类型的局部变量,如果未明确初始化,则内容是不确定的.greet在您的代码中也是如此.
所以,基本上,你试图写入一个有效性未知的内存.指向的内存位置充其量greet是无效的.您必须确保用作目标缓冲区的指针指向某个有效的内存位置.您可以通过以下方式之一完成此操作
使指针指向有效的内存位置,
char *greet = NULL;
char buf[BUFSIZ] = {0};
greet = buf;
.
.
.
fgets(greet, BUFSIZ, stdin);
Run Code Online (Sandbox Code Playgroud)使用动态内存分配器分配内存(在运行时),如
char * greet = malloc(BUFSIZ);
if (greet) {// allocation successful....}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您还需要处理清理工作.
也就是说,不要使用,它是危险的(并从最新标准,AFAIR中删除).请改用. gets()fgets()
作为一方,没有,对于你提到的其他选项,
char greet;也是无效的,fgets()(是的,甚至gets())期望一个指针char,而不是一个char type.启用警告,您的编译器将尖叫.你最好停在那里!!
char greet[]; 语法无效,altotger,无需讨论.
char greet[20];这是正确的,只要你传递一个小于/等于数组大小的大小,就可以了fgets().这没关系因为,
greet是一个自动局部变量,因此将自动分配存储空间并且你将在界限内获得有效的记忆.都好.
指针不是数组.你已经声明了一个指针,但你没有为指针指向的位置分配空间(我们通过动态分配内存malloc()),因此当你尝试写入时greet,你调用Undefined Behavior,这就是为什么它似乎在你的机器上工作正常,现在,但事实并非如此!
另一方面,char greet[20];它将工作,因为它是一个大小为20的数组,准备保存一个字符串.
而且,考虑使用fgets()结束gets().fgets和gets之间的区别.
把所有东西放在一起,我们可以得到:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *greet = malloc(21); // can hold a string of 20 characters, plus NULL terminator
// TODO: Check for malloc failure
printf("Enter name>\n");
fgets(greet, 21, stdin);
printf("Hello %s", greet);
// Never forget to deallocate your dynamic memory!
free(greet);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过使用固定大小的数组,代码看起来像这样:
char greet[21];
printf("Enter name>\n");
fgets(greet, 21, stdin);
printf("Hello %s", greet);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
465 次 |
| 最近记录: |