C++:为什么这段代码给我内存问题/未定义的行为?

标签 c++ memory mbed

一些背景知识,如果你有兴趣......

下一段代码是尝试使用循环冗余校验 (CRC-15) 实现数据包错误代码生成器。这用于检测通信数据损坏。不需要更详细的介绍。

代码和问题

init_PEC15_Table 函数是一个查找表生成器。

pec15 函数接受数据输入,计算解决方案的地址并在查找表中查找结果。

data 是一个 char 数组,我已为其分配了值 1。这将传递给 pec15。

现在,我发现只需重新排序 cout 命令,“stuffed pec”(我感兴趣的输出)的值就会发生变化。通过在线阅读,我了解到这可能是由于内存堆栈以影响结果寄存器的方式意外更改,并且这可能是由于对其他变量的越界操作。我的理解有误吗?

现在,我是初学者,这非常令人生畏。我可能犯了一些我不知道的严重错误,所以请随时将代码撕成碎片。 此外,如果重要的话,此代码在 mbed LPC1768 上运行。

#include <iostream>


using namespace std;

unsigned short pec15Table[256];
const unsigned int CRC15_POLY = 0x4599;



void init_PEC15_Table() // Cyclical Redundancy Check lookup table generator function
{
    unsigned short rem;
    for (int i = 0; i < 256; i++)
    {
        rem = i << 7;
        for (int bit = 8; bit > 0; --bit)
        {
            if (rem & 0x4000)
            {
                rem = ((rem << 1));
                rem = (rem ^ CRC15_POLY);
            }
            else
            {
                rem = ((rem << 1));
            }
        }
        pec15Table[i] = rem & 0xFFFF;
//        cout << hex << pec15Table [i] << endl;
    }
}

 unsigned short pec15(char* data, int lengt = 16)  //Takes data as an input,
{
     int rem, address;
     rem = 16;//PEC seed (intial PEC value)
    for (int i = 0; i < lengt; i++)
    {
        address = ((rem >> 7) ^ data[i]) & 0xff;//calculate PEC table address
        rem = (rem << 8) ^ pec15Table[address];
    }
    return (rem * 2);//The CRC15 has a 0 in the LSB so the final value must be multiplied by 2
}

int main()
{
    init_PEC15_Table();         //initialise pec table
    char data = (short) 0x1 ;   // Write 0x1 to char array containing the data 0x1
    char* dataPtr = &data;      // Create a pointer to that array

    unsigned short result = pec15(dataPtr);                    //Pass data pointer to pec calculator


    cout << "data in: " << (short) *dataPtr << endl;        //Print the short representation of the char data array (Outputs 1)
    cout << "size of data: " << sizeof(*dataPtr) << endl;   //Print the size of the char array (Outputs 1)
    cout << "stuffed pec: " << result << endl;                 //Print the output of the pec calculation    

    return 0;
}

最佳答案

您在此处编写的代码与您编写的注释不同步:

char data = (short) 0x1 ;   // Write 0x1 to char array containing the data 0x1
char* dataPtr = &data;      // Create a pointer to that array

第一行没有向字符数组写入任何内容。相反,它会创建一个数值为 1 的 char 变量。请注意,这里不需要强制转换为 short 并且没有任何效果 - 您是不是想写还有别的吗?

第二行没有创建指向数组的指针。相反,它创建一个指向 data 变量的指针。您可能会将其视为指向长度为 1 的数组的指针,但这可能不是您想要做的。

上面两行本身不会做任何坏事。然而,下一行是一个真正的问题:

unsigned short result = pec15(dataPtr);                    //Pass data pointer to pec calculator

请记住 pec15 有第二个参数,它应该表示传入数据的长度。由于您没有指定它,它默认为 16。但是,您的 dataPtr 指针仅指向单个 char 值,而不是 16 个 char 值,因此这会导致未定义的行为。

我不确定如何解决这个问题,因为我不太了解您的代码背后的意图。你的意思是做一个十六元数组吗?您的意思是创建一个填充值 0x1 的数组吗?此处的正确修复取决于该问题的答案。

关于C++:为什么这段代码给我内存问题/未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56692601/

相关文章:

c++ - 读取无符号整数时如何将负数检测为解析错误?

java - 如何以编程方式获取 jmap 直方图?

ios - 如何为在XCode中以 Debug模式运行的iOS应用程序创建整个内存转储

c - 如何在 mbed-cli 上编译 hal mbed

c - mbed 以太网接口(interface)不工作

c++ - GCC 6.3.0 中的 ODR 违规,类型定义在两个单独的翻译单元中

c++ - Internet Explorer 附加组件列表

c++ - &array[size] 完全安全吗?

c++ - 函数局部变量在函数调用之间持续存在

c++ - 寻找帮助递归扫描目录与 io.h