【问题标题】:c char to int pointerc char 到 int 指针
【发布时间】:2015-10-15 19:24:00
【问题描述】:
#include<stdio.h>

int main(void)    
{
    int arr[3] = {2, 3, 4};
    char *p;
    p = (char*)arr;
    printf("%d", *(int*)(p+1));
    return 0;
}

我在指针上做这个问题。我希望输出是一些垃圾值,因为从 char* 转换为 int* 但输出总是 50331648,这很奇怪。请解释

编辑:我在某个网站上看到了这个输出问题,所以需要根据给定的说明输出

【问题讨论】:

  • P 是 char*,arr 是 int。
  • @user2653926,是的,这是一个问题,因为(p + 1) 可能与int * 不对齐
  • 这能编译吗?您不能将 int 的地址分配给 char 指针。
  • @machine_1 NO :)),因为 来自不兼容的指针类型的赋值
  • 你想解释什么?您正在调用未定义的行为,这就是您得到的。如果您想要“幕后”的解释,请检查阵列的内存转储。

标签: c pointers casting


【解决方案1】:

你正在做的是未定义的行为。

假设sizeof(int) 是 4

小端系统

在小端系统中,arr 的内存布局为:

arr
+----+----+----+----+----+----+----+----+----+----+----+----+
| 02 | 00 | 00 | 00 | 03 | 00 | 00 | 00 | 04 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+----+----+----+

使用时:

char* p = arr;

p    p+1
|    |
v    v
+----+----+----+----+----+----+----+----+----+----+----+----+
| 02 | 00 | 00 | 00 | 03 | 00 | 00 | 00 | 04 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+----+----+----+

如果您将p+1 解释为int*,并将该位置的对象评估为int,您会得到:

+----+----+----+----+
| 00 | 00 | 00 | 03 |
+----+----+----+----+

在小端系统中,这个数字是

0x03000000

等于50331648,也就是你得到的输出。

大端系统

在大端系统中,arr 的内存布局为:

arr
+----+----+----+----+----+----+----+----+----+----+----+----+
| 00 | 00 | 00 | 02 | 00 | 00 | 00 | 03 | 00 | 00 | 00 | 04 |
+----+----+----+----+----+----+----+----+----+----+----+----+

评估*(int*)(p+1)时你会得到的数字是:

+----+----+----+----+
| 00 | 00 | 02 | 00 |
+----+----+----+----+

等于0x0200,即512。

您正在执行的操作是未定义行为的原因应该很明显。

【讨论】:

  • 或者由于访问未对齐,您可以获得bus error
【解决方案2】:

您将 arr 声明为 int 并将 p 声明为 char。您的程序将无法使用现代编译器进行编译。 你在那里尝试的是分配不同类型的指针,这是错误的方法。

我认为这是你需要的:

#include<stdio.h>

int main(void)    {
    int arr[3] = {2, 3, 4};
    char *p;
    p = (char*)arr;
    printf("%d", *(int*)(p+1));
    return 0;
}

输出(垃圾):

50331648

【讨论】:

    【解决方案3】:

    这里逐行解释你的代码,最后解释为什么你会得到那个输出

    //assuming 32-bit machine 
    int arr[3] = {2, 3, 4}; //arr is a pointer to the first element which is an int 2 with a memory size of 4 bytes (int = 4 bytes)
    char *p; //p is declared a pointer to a char implying it points to a 1 byte memory size (char = 1 byte)
    p = (char*)arr; /* p now points to the first element of the array but actually this happens by luck. 
                      here is why: (char*)arr will attempt to cast the int pointer to a char pointer, 
                      in other words, asking it to present whatever took 4bytes to be presented in 1 byte 
                      which will overwrite the least significant bytes. but since numbers are stored in reverse order, 
                      it will overwrite only zeros causing no problem.*/
    printf("%d", *(int*)(p+1)); /* p is still a char pointer holding memory address of 2 in the array. 
                                casting that to int* will add extra bytes from memory. so finally what you're getting is 
                                garbage number which I think is the virtual memory limit, (48 Gb *1024 *1024 = 50331648 Kb)*/
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-28
      • 2012-01-14
      • 1970-01-01
      • 2021-01-26
      • 1970-01-01
      • 2013-06-02
      • 2017-02-12
      • 1970-01-01
      相关资源
      最近更新 更多