c - c 中的内存是如何分配的,为什么两个连续的内存之间的差异总是4?

标签 c pointers malloc dynamic-memory-allocation cs50

#include <stdio.h>
#include <cs50.h>

int main (void)
{
    int *x;
    x = malloc(sizeof(long long)*3);
    scanf("%i %i %i",x, (x+1), (x+2));
    printf("%i\t %i\t %i\n",(int)x, (int)(x+1), (int)(x+2));
    printf("%i\t %i\t %i\n",*x, *(x+1), *(x+2));
    free(x);
}

该程序对于输入 12,2,3 的输出是:

43171856         43171860        43171864
12       2       3

所以,我的问题是为什么每种情况下地址之间的差异都是 4 , 如果 *x指向43171856然后*(x+1)应该指向4317185不是43171860sizeof(long long)也是8 bytes ,那么分配的内存如何分配 8 4 之间的字节43171856 之间的字节和43171860 .

最佳答案

首先,在您的代码中

 printf("%i\t %i\t %i\n",(int)x, (int)(x+1), (int)(x+2));

调用实现定义的行为,因为您试图将指针转换为整数。

如果你想打印指针

  • 使用%p格式说明符
  • 将参数转换为 void *
<小时/>

也就是说,指针算术遵循数据类型。您已将 x 声明为指向 int 的指针,因此任何指针算术都将基于 sizeof(int),无论其计算结果如何您的平台。

引用 C11,第 §6.5.6/P8 章,(强调我的)

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. [....]

在你的代码中,你写了

 x = malloc(sizeof(long long)*3);

这是错误。在这种情况下,您可能会更安全,因为 sizeof(long long)>= sizeof(int),但对于任何任意类型都不是这样。

  • 最好的情况:您最终会浪费内存。
  • 最坏的情况:您最终将访问超出范围(无效)的内存。

更好且更受欢迎的编写方式是

 x = malloc(sizeof*x * 3);   //sizeof is not a function :)

然后,检查 malloc() 是否成功。这会分配所需的确切内存量,不多也不少。

关于c - c 中的内存是如何分配的,为什么两个连续的内存之间的差异总是4?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43451489/

相关文章:

计算 TCP 缓冲区中的数据数

c - 对动态结构的动态数组进行 qsort

c - 重新分配字符串文字

c - 为什么我得到 "increment of pointer to unknown structure"?

c++ - Windows 应用程序的堆大小

c - 使用 calloc 分配内存并释放

c - 另一个动态内存分配错误

c - 是否不允许对操作的左值进行类型转换?

c++ - 以 clang 格式对齐函数声明

c# - 如何获得固定的缓冲区长度?