首页 > 解决方案 > 将 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->elementsis a char** elements.

标签: c

解决方案


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 个字节。


推荐阅读