首页 > 解决方案 > 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 结果(错误):

圆周率结果

标签: c

解决方案


看起来您的问题远不止一个,但让我们从第一个问题开始:

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或类似工具来检查您的代码是否存在未定义的此类错误。


推荐阅读