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

时间:2012-04-21 19:21:49

标签: c malloc dynamic-memory-allocation

我正在使用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:%d\n",sizeof(short));
     d =t;
     (*d) = 65536;
     p = t; 
     *p = 65536;
     printf("\nP:%p: D:%p:\n",p,d);
     printf("\nVAL_P:%d ## VAL_D:%d\n",(*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 - 为短类型。然后我为他们分配了* (p = t和d = t) * 这意味着d&amp; p指向堆上的相同mem位置。

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

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

我的问题是:

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

  2. 即使所有这一切都在发生,如何通过(* p)和(* d)对相同的记忆区域进行反映,打印出两个不同的答案(尽管如果我正在考虑的原因,这也可以解释1)。

  3. 有人可以对此有所了解,我们会非常感激......如果有人可以解释其背后的原因......

    非常感谢

3 个答案:

答案 0 :(得分:2)

首先回答你的第二个问题:

解释是int通常是4个字节,最重要的字节可以存储在前两个位置。仅{2}的short也将其数据存储在前两个位置。显然,将65536存储在intshort中,但指向相同的内存位置,将导致数据存储偏移两个字节{{1} }与int相关,short的两个最低有效字节对应int的存储空间。

因此,当编译器打印short时,它会将其解释为*d并查看与short的存储相对应的区域,这不是编译器先前存储的位置撰写short65536。请注意,写*p覆盖了之前的*p = 65536;,用*d = 65536;填充了两个最不重要的字节。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

1)OS内存管理器的粒度为4K。一位写入不太可能触发AV /段错误,但它会破坏相邻位置的任何数据,导致:

2)未定义的行为。这组行为包括'明确正确的操作',(现在!)。