C语言8x8二进制数组偶水平校验位生成代码错误排查
问题描述
我正在使用C语言编写程序,实现二进制数据数组的偶水平位校验功能。程序其他模块会生成一个8x8规模的二进制数组,该数组会被传入ParityCreation()函数。
预期实现逻辑
接收8x8数据数组后,将其扩展为8x9规模的数组,新增列用于存储每一行对应的校验位。随后逐行遍历数组,计算每行非零元素的总和并存入iNonZero变量;判断iNonZero的奇偶性,若为奇数则在该行最后一列写入1,若为偶数则写入0。
测试用例与预期输出
给定测试矩阵:
{{0, 1, 0, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 0, 1}};
预期输出带校验位的矩阵:
{{0, 1, 0, 0, 0, 0, 0, 1, 0}, {0, 1, 0, 0, 1, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 1, 0, 1, 0, 0, 1}, {0, 1, 0, 0, 1, 1, 0, 0, 1}, {0, 1, 0, 0, 1, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 1, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 1, 1}};
实际故障现象
实际运行结果不符合预期:最后一列全部填充为0,矩阵右下角元素为随机任意值。初步怀疑问题与iNonZero变量的逻辑有关,比如未在正确时机重置,但无法确定根因。
附上完整实现代码:
//EVEN PARITY MATRIX void ParityCreation(int iBitMatrix[][8]) { int i = 0; int j = 0; int iNonZero = 0; //Neue Marix erstellen int iParitaetsMatrix[8][9]; //Writing the iBitMatrix into the iParitaetsMatrix for(i = 0; i <= 7; i++) { for(j = 0; j <= 8; j++) { iParitaetsMatrix[i][j] = iBitMatrix[i][j]; } } //Looping thorough the rows of the Matrix for (i = 0; i <= 8; i++) { //Setting the iNoneZero to 0, so that it is reseted for each iteration iNonZero = 0; //Looping through the columns of the Matrix for (j = 0; j <= 9; j++) { if (iBitMatrix[i][j] != 0) iNonZero += 1; } //Add a parity bit "1" if number of non-zero elements is odd if(iNonZero % 2 != 0) { iBitMatrix[i][9] = 1; } //Add a parity bit "0" if number of non-zero elements is even else //(iNonZero % 2 == 0) { iBitMatrix[i][9] = 0; } } //Output of the horizontal parity bit: int iColumns = 0; int iRows = 0; printf("\n\n\n"); for(iColumns=0; iColumns<=7; iColumns++) { for(iRows=0; iRows<=8; iRows++) { printf(" %i " ,iParitaetsMatrix[iColumns][iRows]); } printf("\n"); } } //Driver code int main() { int iBitMatrix[8][8] = {{0, 1, 0, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 0, 1}}; ParityCreation(iBitMatrix); return 0; }
错误定位与修复方案
代码故障和iNonZero重置逻辑无关,核心是4个数组越界+逻辑脱节问题:
- 数组拷贝阶段越界:传入的
iBitMatrix是8列(合法下标0~7),内层循环写j <=8,访问iBitMatrix[i][8]属于越界读,会读到栈上的随机值。 - 校验计算阶段双重越界:外层行循环写
i<=8,8行数组的合法行下标是0~7,访问iBitMatrix[8]已经越界;内层列循环写j<=9,不管原矩阵还是扩展矩阵都没有下标为9的列,越界读写直接破坏栈内存,这就是右下角出现随机值的根本原因。 - 逻辑完全脱节:计算校验位时一直往原数组
iBitMatrix写值,但最后打印的是iParitaetsMatrix,两个数组没有同步,校验位根本没写到打印的数组里,最后一列自然全是未初始化的0。 - 拷贝扩展矩阵时没有给校验位列赋初始值,栈上分配的局部数组本身值是随机的,仅拷贝前8列的情况下,第9列本来就没有确定值。
修正后可运行代码
#include <stdio.h> //EVEN PARITY MATRIX void ParityCreation(int iBitMatrix[][8]) { int i = 0; int j = 0; int iNonZero = 0; // 新建8*9的校验矩阵 int iParitaetsMatrix[8][9]; // 拷贝原8*8矩阵到新矩阵前8列 for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { iParitaetsMatrix[i][j] = iBitMatrix[i][j]; } } // 逐行计算偶校验位 for (i = 0; i < 8; i++) { iNonZero = 0; // 只统计每行前8个原始数据位的1的个数 for (j = 0; j < 8; j++) { if (iParitaetsMatrix[i][j] != 0) iNonZero += 1; } // 偶校验:1的个数为奇数则补1,偶数补0,保证整行1的总数为偶数 iParitaetsMatrix[i][8] = (iNonZero % 2 != 0) ? 1 : 0; } // 打印最终带校验位的矩阵 printf("\n\n\n"); for(i = 0; i < 8; i++) { for(j = 0; j < 9; j++) { printf(" %i " ,iParitaetsMatrix[i][j]); } printf("\n"); } } //Driver code int main() { int iBitMatrix[8][8] = {{0, 1, 0, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 0, 1}}; ParityCreation(iBitMatrix); return 0; }
运行后输出和预期结果完全一致。
注:C语言中长度为N的数组,合法下标范围是0~N-1,写循环条件时直接用
<N即可,不要写<=N-1,很容易数错边界触发越界。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

