'c'问题中的动态内存分配



我正在使用malloc编写代码,然后遇到了一个问题,所以我写了一个测试代码,它实际上总结了下面的整个混乱:

# include <stdio.h>
# include <stdlib.h>
# include <error.h>
int main()     
{
     int *p = NULL;
     void *t = NULL;
     unsigned short *d = NULL;
     t = malloc(2);
     if(t == NULL) perror("n ERROR:");
     printf("nSHORT:%dn",sizeof(short));
     d =t;
     (*d) = 65536;
     p = t; 
     *p = 65536;
     printf("nP:%p: D:%p:n",p,d);
     printf("nVAL_P:%d ## VAL_D:%dn",(*p),(*d));
     return 0;
  }
   Output:: abhi@ubuntu:~/Desktop/ad/A1/CC$ ./test
            SHORT:2
            P:0x9512008: D:0x9512008:
            VAL_P:65536 ## VAL_D:0

我正在使用 malloc 分配 2 字节的内存。返回 void * 指针的 Malloc 存储在 void* 指针 't' 中

然后 2 个指针被声明为 p - 整数类型和 d - 短类型。 然后我把t分配给它们*(p =t和d=t)*,这意味着d和p都指向堆上的相同mem位置。

在尝试将 65536(2^16) 保存到 (*d) 时,我收到警告说大 int 值被截断,这是预期的。现在我再次将 65536(2^16) 保存到 (*p),这没有引起任何警告。

*

在打印 (*p) 和 (d) 时,我得到了不同的值(尽管每个值都针对自己定义的指针类型正确)。

我的问题是:

  1. 虽然我已经使用 malloc 分配了 2 个字节(即 16 位)的堆内存,但我如何在这两个字节中保存 65536(通过使用整数类型的指针 (p))。??我有一种感觉,造成这种情况的原因是 void 到 int* 指针(在 p = t 中)的自动类型融合,所以将 t 分配给 p 会导致访问通过 malloc 分配的内存区域之外的内存区域。??.

  2. 即使所有这一切都在发生,通过 (*p) 和 (*d) 取消对同一内存区域的引用会打印两个不同的答案(尽管如果我在思考问题 1 中的原因,这也可以解释)。

有人可以对此有所了解吗,将不胜感激。如果有人可以解释这背后的原因..

非常感谢

先回答你的第二个问题:

解释是,int通常为 4 个字节,最高有效字节可能存储在前两个位置。 只有 2 个字节的short也将其数据存储在前两个位置。 显然,将65536存储在intshort中,但指向相同的内存位置,将导致相对于shortint数据存储偏移两个字节,int的两个最低有效字节对应于short的存储。

因此,当编译器打印*d时,它会将其解释为short并查看对应于short存储的区域,这不是编译器在写入*p时先前存储65536的位置。 请注意,写入*p = 65536;会覆盖前一个*d = 65536;,用 0 填充两个最低有效字节。

关于第一个问题:编译器不会65536存储在 2 个字节内*p。 它只是超出了您分配的内存范围 - 这可能会导致某个时候的错误。

在 C 中,对于超出分配范围写入根本没有保护。只是不要这样做,任何事情都可能发生。在这里,它似乎对您有用,因为巧合的是,您分配的两个字节后面的空间不用于其他用途。

1) 操作系统内存管理器的粒度为 4K。 一位的 ovewrite 不太可能触发 AV/段错误,但它会损坏相邻位置中的任何数据,从而导致:

2)未定义的行为。 这组行为包括"非常正确的操作",(目前!

相关内容

  • 没有找到相关文章

最新更新