c - 将 1 个字符的空间分配给 int 指针
问题描述
我正在学习 C 并且有点困惑为什么我没有从 GCC 收到以下代码段的任何警告/错误。我正在为指向 int 的指针分配 1 个字符的空间,这是 GCC 所做的一些更改(比如默默地优化分配的空间为 int)?
#include <stdlib.h>
#include <stdio.h>
typedef int *int_ptr;
int main()
{
int_ptr ip;
ip = calloc(1, sizeof(char));
*ip = 1000;
printf("%d", *ip);
free(ip);
return 0;
}
更新
阅读了下面的答案后,如果我反过来做,例如将 int 的空间分配给指向 char 的指针,它是否仍然不安全和有风险?我困惑的根源是Rosetta Code中的以下答案,在函数StringArray StringArray_new(size_t size)
中,编码器似乎正是在执行此操作this->elements = calloc(size, sizeof(int));
where this->elements
is a char** elements
.
解决方案
calloc 的结果是void*
隐式转换为类型的int*
类型。C 编程语言和 GCC 只是信任程序员编写合理的转换,因此不会产生任何警告。您的代码在技术上是有效的 C,即使它在运行时产生无效的内存写入。所以不,GCC 不会为整数隐式分配空间。
如果您想在运行(或编译)之前看到此类警告,您可能需要使用例如 Clang 静态分析器。
如果您想在运行时查看此类错误,请使用 Valgrind 运行您的程序。
更新
为 1 分配空间int
(即通常为 4 个字节)然后将其解释为 a char
(1char
为 1 个字节)不会导致任何内存错误,因为 an 所需的int
空间大于 a 所需的空间char
。实际上,您可以将结果用作 4 的数组char
。运算符以字节数返回该sizeof
类型的大小。然后该calloc
函数分配该字节数,它不知道将在分配的段中存储什么类型。
虽然这不会产生任何错误,但它确实可以被认为是一种“危险且不安全”的编程实践。高级应用程序存在例外情况,您希望重用相同的内存段来存储不同类型的值。
您链接到的 Rosetta Code 上的代码恰好在该行中包含一个错误。char*
它应该为 a而不是a 分配内存int
。这些通常是不相等的。在我的机器上,an 的大小int
是 4 个字节,而 a 的大小char*
是 8 个字节。
推荐阅读
- c - Explain the result of my C code. K&R "The C Prog language" Ex1-6
- xpages - 使用 Selenium IDE 测试 XPage
- .htaccess - htaccess 重定向最多三个变量
- jquery - 以角度提交后如何关闭模态?
- python - 在 python 中为许多字典中的每一个打开文件
- android - 如何在 gradle 中运行其他 gradle 命令
- go - 每个前端的 Traefik 转发身份验证
- php - Laravel 调度程序延迟运行(不准时)
- django - * 之后的 _reverse_with_prefix() 参数必须是可迭代的,而不是 int
- php - Web 开发中的预定事件