【问题标题】:Multiple int arrays pointing to same memory address?多个指向相同内存地址的int数组?
【发布时间】:2014-06-01 12:29:01
【问题描述】:

我的 Arduino 代码中有一个对我来说似乎没有意义的错误。总体而言,此代码将通过存储有关要播放到压电(单音扬声器)的音符的频率和持续时间的信息来播放音乐。为了节省内存,我声明/初始化了两个单独的数组(作为 TuneManager 类的一部分),它们将保存下一组频率/持续时间,有两个索引:currentNoteIndex(它跟踪接下来将播放哪个音符) 和 loadableNoteIndex(它跟踪数组中可以被新的笔记信息覆盖的下一个位置)。

int currentNoteIndex = 0;
int loadableNoteIndex = 0;
int tuneFreq[MAX_NOTE_BUFFER];
int tuneDur[MAX_NOTE_BUFFER];

然后,当需要将更多音符加载到这些数组中时,我从代表歌曲的字符串中解密它们并像这样加载它们:

tuneFreq[loadableNoteIndex] = atoi(noteFreq);
tuneDur[loadableNoteIndex] = atoi(noteDur);

如果我同时打印出 noteFreq 和 noteDur 变量,我会得到预期值。不幸的是,如果我取出保存的数组值,我会得到不正确的输出。

Serial.print(tuneFreq[loadableNoteIndex]);
Serial.print(" ");
Serial.print(tuneDur[loadableNoteIndex]);

例如,如果 noteFreq 为 150,但 noteDur 为 200,则输出将为“200 200”,而不是预期的“150 200”。此外,如果我在打印之前切换赋值语句的顺序,它将打印“150 150”而不是“200 150”。这让我相信两个数组都以某种方式引用了相同的内存地址,但我无法找出问题所在。

如果您想要完整的代码,请在此处查看 TuneManager cpp 和 h 文件:https://github.com/bajuwa/RoboKitty/tree/TuneBuffer/EightBitTunes

【问题讨论】:

    标签: c++ arduino


    【解决方案1】:

    您的数组在标头中声明不正确:

    private:
      int tuneFreq[];
      int tuneDur[];
    

    这声明了两个大小为零的数组(即使你在源文件中分配数组也没关系),这是非法的(某些编译器,例如GCC,允许它们)

    你必须在头文件中声明大小,让编译器知道你的类型的大小:

    private:
      const int MAX_NOTE_BUFFER = 25;
      int tuneFreq[MAX_NOTE_BUFFER];
      int tuneDur[MAX_NOTE_BUFFER];
    

    您的程序当前具有未定义的行为(您正在写入超出“数组”的末尾),因此无论您观察到什么(实际上您正在写入超出对象的某些内存)都可以被认为是巧合。

    您在同一个位置写入两次(一个大小为零的数组的大小为 ... 零)这一事实解释了为什么它看起来像“两个数组具有相同的地址”,但具有未定义的行为,其他任何东西可能发生。

    【讨论】:

    • 这不是零大小的,它是illegal
    • 谢谢!这很好地治愈了我的头痛 x) 我是如此专注于这一切的巧合,以至于我什至没有想到头文件 x.x
    • gcc 允许:gcc.gnu.org/onlinedocs/gcc/Zero-Length.html,但我会编辑。
    猜你喜欢
    • 2019-04-07
    • 2013-11-06
    • 2022-11-02
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    相关资源
    最近更新 更多