指针中的奇怪错误

Weird bug in pointers

我试图通过下面的代码访问一个 int 值的单个字节。我的问题是,每当我尝试从代码中删除 long int i=0; 时,它都会给我一个分段错误。发生这种情况有什么原因吗?我没有在代码中的任何地方使用 I。

// Online C++ compiler to run C++ program online
#include <iostream>

int main() {
    // Write C++ code here
    
    unsigned int* a; 
    
    unsigned char* b1;
    unsigned char* b2; 
    unsigned char* b3; 
    unsigned char* b4;
    
    *a= 4294967295; //set to max val (4 bytes)
    //*************************
    long int i=0;//Q. Why long int/long long int? 
    //*************************
    
    b1 = (unsigned char*)(a);
    b2 = b1+(long long int)1;
    b3 = b1+(long long int)2;
    b4 = b1+(long long int)3;
    
    std::cout <<*a<<" "<<(int)*b1<<" "<<(int)*b2<<" "<<(int)*b3<<" "<<(int)*b4<<std::endl;
    
    
    return 0;
}

这表现出未定义的行为:

unsigned int* a; 
*a= 4294967295; //set to max val (4 bytes)

指针变量a从未被初始化为任何东西,所以它指向一个随机内存地址。向该随机垃圾地址写入任何内容(通常)会导致分段错误。添加另一个变量会改变行为(由于程序内存布局的变化)只是巧合。

发布的程序有未定义的行为(1):

unsigned int* a;  // Uninitialized local variable, it has an indeterminated value. 
*a = 4294967295;  // Where is it assigned?

不幸的是它恰好在您的环境中“工作”,您应该enable more warnings

自 C++20 起,您可以使用 std::bit_cast 重新解释对象表示:

#include <array>
#include <bit>
#include <iostream>

int main()
{
  auto a{ 4294967295LL };
  using repr_t = std::array<std::byte, sizeof(a)>;
  
  auto b{ std::bit_cast<repr_t>(a) };
  
  // The following outputs:      4294967295   255 255 255 255 0 0 0 0
  std::cout << a << "  ";
  for (auto i : b)
    std::cout << ' ' << static_cast<int>(i);
  std::cout << '\n';    
}

(1) 参见例如:

Undefined, unspecified and implementation-defined behavior

Where exactly does C++ standard say dereferencing an uninitialized pointer is undefined behavior?