char p[0]表示自动分配的缓冲区还是安全指针
Is char p[0] represents an auto allocated buffer or a safe pointer?
这是C++代码,它显示编译器警告,但运行良好。预期的行为如下,但是:
char sz[] = "Hello World";
char *p;
snprintf(p, 12, sz);
printf("%s", p);
上面的代码在运行时,由于没有分配*p而崩溃。好的
char sz[] = "Hello World";
char p[0];
snprintf(p, 12, sz);
printf("%s", p);
上面的代码运行良好,将显示"Hello World"而不会出现任何错误。编译上面的代码时显示编译器警告,使用[0]是非法的,但运行良好。
为什么会这样?
为什么会这样?
它仍然是未定义的行为。
它在您的设置中起作用,因为巧合的是,保存"Hello World"
的数组与堆栈中的变量p
相邻。
不要依赖这样的代码,也不要使用它们。这种代码的行为可以随着编译器的变化、使用不同的编译器选项等而变化。
此
char p[0];
在链接器决定的位置定义一个长度为0的字符数组
没有空间打印任何内容。
与相比的唯一差异/改进
char *p;
后者甚至没有让链接器决定将零大小的空间放在哪里。
您需要打印空间。这两种方法都没有提供/保留任何。
更改为
char p[<N>];
<N>
是一个适当的高数字,以确保足够的空间,如果您可以在编译前决定一个的话。
使用
char* p;
/* ... */
p = malloc(<N>);
如果您在运行前不知道合适的大小。
正如您所期望的,第一个代码段通过访问未初始化的指针(无效内存(来调用未定义的行为。好的
第二个代码段是一个约束冲突。对于像p[0]
这样的数组声明,引用C11
,第6.7.6.2章,(emphasis mine(
除了可选的类型限定符和关键字
static
之外,[
和]
还可以分隔表达式或CCD_ 9。如果它们对表达式(指定数组的大小(进行定界表达式应具有整数类型如果表达式是常量表达式,则应具有大于零的值[….]
因此,代码不是有效的,编译器不应该从该代码中生成二进制代码。增加编译器警告。
char sz[] = "Hello World";
char *p;
snprintf(p, 12, sz);
printf("%s", p);
correct将获得错误内存而不分配
char sz[] = "Hello World";
char p[0];
snprintf(p, 12, sz);
printf("%s", p);
一些编译器根据字符串长度分配大小,但大多数情况下我们应该避免这种情况,这是编译器相关的问题,与snprintf
无关
- 将字符缓冲区强制转换为函数指针
- 将指针作为缓冲区传递到第一个字符串元素
- 将constexpr字节数组与缓冲区的一部分(指向数据的指针)进行比较
- char p[0]表示自动分配的缓冲区还是安全指针
- 指针符号在参数规范中表示什么,例如:(char16 *缓冲区,int32 大小)?C++
- OpenGL:使用指向静态数据的指针数组传递缓冲区数据
- 重置/包装 C/C++ 中的变量(环缓冲区指针)
- 将 char* 推送到矢量时出现问题,但在每次迭代后,它会将指向相同值缓冲区的指针添加到矢量中
- 返回指向矢量数据的指针,而不复制缓冲区和内存泄漏
- memcpy指向炭缓冲区的指针
- 来自 2 个指针的组合缓冲区,无需复制
- 来自指针向量的OpenGL阵列缓冲区
- C++:使用std::ifstream读取二进制文件后删除缓冲区/指针时发生访问冲突
- 如何将一个缓冲区指针的内容复制到另一个缓冲区指针
- 正在将缓冲区/指针设置为null
- 将额外的字节填充到要通过网络发送的flatbuffer的缓冲区指针
- 从缓冲区指针计算堆栈中的返回地址
- MPI_scatter:缓冲区指针无效
- MPI_Pack:无效缓冲区指针
- GetIndices()会在CreateIndexBuffer()和SetIndices()之后返回相同的缓冲区指针吗?