【问题标题】:Data stored with pointers用指针存储的数据
【发布时间】:2014-11-23 04:02:04
【问题描述】:
void *memory;
unsigned int b=65535; //1111 1111 1111 1111 in binary
int i=0;

memory= &b;

for(i=0;i<100;i++){
    printf("%d, %d, d\n", (char*)memory+i, *((unsigned int * )((char *) memory + i)));
}

我试图理解一件事。

(char*)memory+i - 打印出 2686636 - 2686735 范围内的地址。

当我使用 memory= &b 存储 65535 时,这应该将此数字存储在地址 2686636 和 2686637 因为每个地址只有一个字节所以 8 个二进制字符所以当我打印出来时

*((unsigned int * )((char *) memory + i)) 这应该打印 2686636, 255 和 2686637, 255

而不是它打印 2686636、65535 和 2686637,随机数

我正在尝试实现内存分配。是学校项目。这应该代表内存。一个地址应该是一个字节,因此标头将是 2686636-2586639(4 个字节表示块大小)和 2586640(1 个字节字符表示空闲或已用内存标志)。谁能给我解释一下谢谢。

感谢您的回答。

void *memory;
void *abc;

abc=memory;
for(i=0;i<100;i++){
*(int*)abc=0;
abc++;
}

*(int*)memory=16777215;

for(i=0;i<100;i++){
    printf("%p, %c, %d\n", (char*)memory+i, *((char *)memory +i), *((char *)memory +i));
}

输出是

0028FF94,  , -1
0028FF95,  , -1
0028FF96,  , -1
0028FF97,  , 0
0028FF98,  , 0
0028FF99,  , 0
0028FF9A,  , 0
0028FF9B,  , 0

我认为它有效。 255 只有一个 -1、65535 2 次 -1 和 16777215 3 次 -1。

【问题讨论】:

  • 只删除 unsigned int 吗?现在的输出是 2686636, -1 和 2686637, -1
  • 我这样做 printf("%p, %c, %d\n", (char*)memory+i, *((char *) memory + i), *((char * ) 记忆 + i));它给出了 2686636, ,-1 但我注意到当我使 b = 65535 前 2 个地址是空格时,-1 但是当我使 b = 4294967295 前 4 个地址是空格时,-1 和 4294967295 是 32 位所以我认为它以某种方式工作。
  • 我更改了代码,我认为它现在可以正常工作,请检查我最后发布的问题
  • 我很惊讶第二部分有效!
  • 为什么?我试过这个 (char)memory='a';而不是某个数字,输出为 0028FF94、a、97,所有其他内存单元为 0。所以我认为没关系,它的工作原理应该是这样。

标签: c pointers byte bit


【解决方案1】:

在您的程序中,b 的地址似乎是 2686636,当您写入 (char*)memory+i 或 (char*)&b+i 时,这意味着该指针指向 char,因此当您向其添加一个时仅跳转到一个内存地址,即 2686637 等直到 2686735(即(char*)2686636+99)。


现在,当您取消引用 ie*((unsigned int * )((char *) memory + i))) 时,您将获得该内存地址的值,但您只给 b 赋值(其地址为2686636).所有其他内存地址都有您正在打印的垃圾值。


所以首先你必须在其余地址(2686637 到 2686735)存储一些数据 祝你好运.. 我希望这会有所帮助

【讨论】:

    【解决方案2】:

    我昨天在我的 cmets 中没有提到这一点,但很明显,从 0 到 100 的 for 循环超出了无符号整数的大小。

    我只是忽略了代码中的一些明显问题,并试图就您提出的实际问题给出提示(除了方便 :-) 之外,很难做更多的事情)。不幸的是,我昨天没有时间完成这个。所以,延迟一天我给你的提示。

    尽量避免假设某个类型有多大(比如 2 个字节或 4 个字节)。即使您的假设现在成立,如果您切换编译器或切换到另一个平台,它也可能会改变。因此,在整个代码中使用 sizeof(type)。如需对此进行更长时间的讨论,您可能需要查看:size of int, long a.s.o. on Stack Overflow。该标准仅规定某种类型应该能够容纳的范围(0-65535 用于 unsigned int),因此仅适用于类型的最小大小。这意味着 int 的大小可能(并且通常是)大于 2 个字节。除了原始类型之外,sizeof 还可以帮助您计算结构的大小,由于内存对齐 && 打包结构的大小可能与您通过简单查看其属性“预期”的大小不同。所以 sizeof 运算符是你的朋友。

    确保在 printf 中使用正确的格式。

    小心使用指针算术和强制转换,因为结果取决于指针的类型(显然也取决于您添加的整数的值)。

    (unsigned int*)memory + 1 != (unsigned char*)memory + 1

    (unsigned int*)memory + 1 == (unsigned char*)memory + 1 * sizeof(unsigned int)

    以下是我将如何编写代码:

    //check how big is int on our platform for illustrative purposes
    printf("Sizeof int: %d bytes\n", sizeof(unsigned int));
    
    //we initialize b with maximum representable value for unsigned int
    //include <limits.h> for UINT_MAX
    unsigned int b =  UINT_MAX; //0xffffffff (if sizeof(unsigned int) is 4)
    
    //we print out the value and its hexadecimal representation
    printf("B=%u 0x%X\n", b, b);
    
    //we take the address of b and store it in a void pointer
    void* memory= &b; 
    
    int i = 0;
    
    //we loop the unsigned chars starting at the address of b up to the sizeof(b) 
    //(in our case b is unsigned int) using sizeof(b) is better since if we change the type of b
    //we do not have to remember to change the sizeof in the for loop. The loop works just the same
    for(i=0; i<sizeof(b); ++i)
    {
        //here we kept %d for formating the individual bytes to represent their value as numbers
        //we cast to unsigned char since char might be signed (so from -128 to 127) on a particular 
        //platform and we want to illustrate that the expected (all bytes 1 -> printed value 255) occurs.
        printf("%p, %d\n", (unsigned char *)memory + i, *((unsigned char *) memory + i));
    }
    

    我希望这对您有所帮助。祝你的学校作业好运,我希望你学到了一些现在和将来可以使用的东西:-)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 2015-06-24
      相关资源
      最近更新 更多