我是学计算机科学的大四学生,以前从未见过如此奇怪的行为.我肯定有一些C语言的复杂性我不理解,但我现在完全不知所措.

我实现了以下功能:

Declaration

void parse_resp(unsigned char *resp, unsigned char *chunk, unsigned int *opcode, unsigned char *opparams, unsigned int *nonce, unsigned char *treasure, int *offset); 

Basically just a function where I pass a punch of pointers to get populated

Definition

void parse_resp(unsigned char *resp, unsigned char *chunk, unsigned int *opcode, unsigned char *opparams, unsigned int *nonce, unsigned char *treasure, int *offset)
{
    int chunklen = resp[0];
    memcpy(&chunk[0], &resp[1], chunklen);
    memcpy(opcode, &resp[chunklen + 1], 1);
    memcpy(&opparams[0], &resp[chunklen + 2], 2);
    memcpy(nonce, &resp[chunklen + 4], 4);
    *nonce = htonl(*nonce);
}

Variable Initialization

unsigned char treasure[1024];
int offset = 0;
unsigned char chunk[127];
unsigned int opcode;
unsigned char opparams[2];
unsigned int nonce;

但这就是奇怪的地方.

Note:我知道这个错误有相当简单的解决方法,但我想先了解一下发生了什么.

推荐答案

opcode的类型int很可能是4个字节,但您只将一个字节复制到其中:

memcpy(opcode, &resp[chunklen + 1], 1);

所以其他3个字节没有初始化,因此有indeterminate values个字节.因此,充其量也不能保证这些字节有任何特定的值,改变parse_resp的调用方式就足以改变那些未初始化字节的值.

在某些情况下,读取未初始化的变量可能会触发undefined behavior,但是由于opcode的地址已被占用,所以这不是问题(除非您使用的是具有inttrap 表示的异域体系 struct ).

将此变量和关联参数的类型更改为unsigned char.

C相关问答推荐

为什么 memcpy() 随机不复制正确的值?

为什么启用优化时 GCC 11 编译器会产生奇怪的输出?

Gnuplot 和 C - 绘制不同的符号/ colored颜色

在 C 中使用数组而不是向量

幂函数给出的答案与 C 中的 math.pow 函数不同

确定在嵌入式 C 中运行时使用哪个变量

在编译时构建静态数组

判断由大括号组成的输入字符串是否格式正确

通过默认网关地址的硬件地址而不是以太网多播地址发送多播

为什么 malloc() 被认为是库调用而不是系统调用?

为什么使用 MOV 指令将 XOR 交换优化为普通交换?