c - C 程序在树莓派上无法正常运行
问题描述
我目前正在设计一个包边代码。这段代码在我的电脑上运行良好,但是当我将它移植到我的 pi 上时,它就无法正常运行。我不知道为什么,而且我对 C 和树莓派还是很陌生。任何帮助将不胜感激。
以下是我的完整代码:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int main(void){
int bitLen, errorLoc;
printf("\nLength of the data bits: ");
scanf("%d", &bitLen);
char binStr[ bitLen ], binStrErr[ bitLen ];
printf("Data stream without error: ");
scanf("%s", &binStr);
if(strlen(binStr) > bitLen || strlen(binStr) < bitLen)
{
printf("\nLength of data stream given does not match stated input length!");
return 0;
}
printf("Location of data bit that has error: ");
scanf("%d", &errorLoc);
if(errorLoc > bitLen)
{
printf("\nValue given is bigger than the input length!");
return 0;
}
//Number Of Check Bits Needed
int rBit = 1;
while (pow(2, rBit) < (bitLen + rBit + 1))
{
rBit = rBit + 1;
}
int checkBitsArr[rBit];
int checkBitsErrArr[rBit];
//Actual size of array
bitLen = bitLen + rBit;
int binNum[bitLen];
int binNumErr[bitLen];
int size = sizeof(binNum) / sizeof(binNum[0]);
int binNumPos = size;
printf("\nData stream: ");
//Flipping the error bit and storing into another string
printf("\nOriginal data stream: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStr[i]);
if(i == (strlen(binStr)) - errorLoc){
int temp = ((binStr[i] - '0') == 0) ? 1 : 0;
binStrErr[i] = temp + '0';
}
else{
binStrErr[i] = binStr[i];
}
}
printf("\nData stream with error: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStrErr[i]);
}
//Filling in the bits into two arrays: One is the correct data stream and one with error
for (int i = strlen(binStr); i >= 0; i--)
{
binNum[binNumPos] = binStr[i] - '0';
binNumErr[binNumPos] = binStrErr[i] - '0';
binNumPos--;
}
printf("\n\n");
//Moving bits to left to make space
int position = 1;
for (int i = size - 1; i >= 0; i--)
{
if ((position & (position - 1)) == 0)
{
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
binNum[i] = 33;
binNumErr[i] = 33;
}
position++;
}
//Settings check bits into place
position = 1;
int checkBitIndex = 0;
for (int i = size - 1; i >= 0; i--)
{
//Get check bit position
if ((position & (position - 1)) == 0)
{
int temp = 0;//number of 1s in relation to the check bit
int tempErr = 0;
int maxNum = (i - position) + 1;
if (maxNum < 0)
maxNum = maxNum + (-1 * maxNum);
//first part of check
while (maxNum < i)
{
if (binNum[maxNum] == 1)
{
temp++;
}
if (binNumErr[maxNum] == 1)
{
tempErr++;
}
maxNum++;
}
int startNum = (i - position) + 1;
//If the start number is less than zero, make it zero
if (startNum < 0)
startNum = startNum + (-1 * startNum);
//Skip check method. Get the next set of check values in relation to the current check bit
for (int x = startNum - (position * 2); x >= 0; x = x - (position * 2))
{
int k = 0;
while (k < position)
{
if (binNum[x + k] == 1)
{
temp++;
}
if (binNumErr[x + k] == 1)
{
tempErr++;
}
k++;
}
}
//Set the value of check bit
binNum[i] = (temp % 2 == 0) ? 0 : 1;
binNumErr[i] = (tempErr % 2 == 0) ? 0 : 1;
//Replace the current value with the correct checkbit
checkBitsArr[checkBitIndex] = binNum[i];
checkBitsErrArr[checkBitIndex] = binNumErr[i];
temp = 0;
tempErr = 0;
checkBitIndex++;
}
position++;
}
printf("\nSEC code: ");
printf("\nOriginal data stream: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNum[i]);
}
printf("\nData stream with error: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNumErr[i]);
}
printf("\n\n");
int checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits without error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits with error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsErrArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
int posError = 0;
printf("\n\nSyndrome code: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
int x = checkBitsErrArr[i] ^ checkBitsArr[i];
if(x == 1){
posError += checkIndex;
}
printf("C%d: %d ", checkIndex, x);
checkIndex = checkIndex/2;
}
printf("\n\n");
printf("\nPosition of error: %d\n\n", posError);
// printf("\n\n");
return 0;
}
这些是 scanf 的输入:
Length of the data bits: 16
Data stream without error: 0011001100110011
Location of data bit that has error: 8
以下是我在计算机和 pi 上的结果:
计算机结果(正确):
Pi 结果(错误):
解决方案
看起来您的问题远不止一个,但让我们从第一个问题开始:
char binStr[ bitLen ], binStrErr[ bitLen ];
您接下来请求的字符串不仅包含作为输入的 16 个字节,还包含一个附加的标记字符作为第 17 个字符。
因此,此时您已经有 2 次缓冲区溢出,您已经可以在 Pi 的输出中很好地看到。第一个示例中也发生了相同的缓冲区溢出,只是内存布局不同,因此不会产生可见的伪影。
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
这是下一个缓冲区溢出,这一次实际上是一个下溢。您正在写入的是内存指向binNum[-1]
之外的内存位置。binNum
无论如何,缓冲区溢出意味着您的程序的行为是未定义的。
习惯使用valgrind或类似工具来检查您的代码是否存在未定义的此类错误。
推荐阅读
- java - 如何获得与 sparkWebUi 相同的真实流程
- php - PHP 错误:在 Codeigniter 中只能通过引用传递变量
- database - 一个额外的列,用于解释同一行中的值何时更新
- python - 如何在 webdriver selenium google chrome 中找到没有 id、name 和 xpath 的元素
- python - 如何从源代码构建 MultiNEAT?
- java - FIX 市场数据、QuickFIX 还是其他?
- java - spring boot如何改变默认的classloader使用setContextClassLoader?
- blazor - 如何获取服务器端 Blazor 应用程序的基本 URL
- android - 关于Android can't load json file in Application.persistentDataPath
- r - 使用 R 中的 pROC 使用单个阈值和 0.5 的阈值梯度改变灵敏度和特异性