【问题标题】:Return dynamic array in C++在 C++ 中返回动态数组
【发布时间】:2010-06-23 15:40:11
【问题描述】:

我需要从一个函数返回一个无符号整数*。下面的代码可以编译,但会在 Windows 64 位机器上运行时崩溃。我知道我在某个地方犯了一个愚蠢的错误,有人可以为我指出。 :p。我还在头文件中声明了该函数,所以我知道它不是那个错误。

请注意,我已经审查了变量名称和编号,因为此函数存在的问题尚未公开发布。

功能:

 unsigned int* convertTime(unsigned int inputInteger, unsigned short inputFrac) {
    unsigned int* output = new unsigned int[2];
    double messageTimeFraction = double(inputFrac) * 20e-6;

    output[1] = unsigned int(inputInteger + 2209032000);
    output[2] = unsigned int(messageTimeFraction * 2e32);

    return output; // Seconds
}

实施:

unsigned int* timeStamp;
timeStamp = convertTime(inputInteger,inputFrac);

【问题讨论】:

  • 请注意,unsigned int(...) 强制转换不是严格有效的(Visual C++ 支持它作为扩展)。有a related, somewhat technical question about this。您可以只使用unsigned(...),也可以使用(unsigned int)(...)。
  • 我希望你在函数返回的 ptr 上调用 delete[],否则你会有内存泄漏...最好使用一个包含两个 int 的结构
  • 如果我记得我的 C++ 正确 unsigned(something) 不是强制转换而是构造函数,创建一个临时的。所以给定的代码肯定不是 C。C 的适当强制转换是 (unsigned long)(...) 而对于 C++,它将是 static_cast(...)
  • 我相信 int 在 Visual C++ 编译为 64 位应用程序中是 32 位,所以 unsigned int(inputFrac * 2e32) 将毫无意义,几乎可以肯定一致为 0。这不应该导致崩溃,但无论如何它可能是一个错误。另外,2209032000 是一个无意义的幻数,messageTimeFraction 是不用的。如果这不是完整的功能,请告诉我们。

标签: c++ arrays function dynamic


【解决方案1】:

嗯,对于初学者来说,你有 output[1] 和 output[2]。数组在 c/c++ 中是零索引的,所以它们应该是:output[0] 和 output[1]。

但是,既然你问的是 c++……我强烈建议你使用 std::vector 或 std::pair。

(当然,为了便于阅读,您可能只想使用一个具有有用字段名称的简单结构)

【讨论】:

  • 因为向量不适合表示恰好有两个整数字段的数据,每个字段都有特定的含义(秒和小数)。
  • @Pete:在使用动态数组的情况下,std::vector总是要好得多。如果std::vector 不合适(实际上,这应该是一个有两个成员的struct),那么动态数组也是如此。所以你应该评论问题。在这个答案上,您的否决票是不公平且不合理的。
  • @sbi 阅读代码。此处不应使用动态分配的数组(它不会改变大小,因此它不是动态数组),因此将其替换为向量并不是一个好建议。由于它已被编辑以推荐结构,因此我删除了 -1。
  • @Pete Kirkham :这就是为什么我说要考虑一个结构或对,传递输出参数是另一种选择。根据您的想法,返回一个包含两个元素的动态数组同样不合适......除非您不需要在向量上调用 delete[]。
  • @Pete :感谢您删除。顺便说一句,你知道......在添加结构引用之前我没有阅读你的答案。当我的答案中的 sn-ps 最终出现在其他人的帖子中时,我一直认为这很糟糕。
【解决方案2】:

我知道我犯了一个愚蠢的错误 某处,有人能指出来吗 对我来说

当然,和Q的主题无关:

output[2] = unsigned int(inputFrac * 2e32);

output 中的正确条目是 [0] 和 [1] - 您的索引超出了范围。 “未定义行为”结果(例如,您观察到的崩溃)。

【讨论】:

  • 它实际上可能与问题的主题有关。该代码正在写入它不应该在免费存储中的内存位置。根据免费存储的实现方式,它可能会覆盖一些重要的东西,从而导致稍后崩溃。
  • @David,如果将短数组分配在堆栈上,则可能会发生完全相同的情况-由编译器来精确布置存储空间,越界写入您可能会覆盖返回地址或其他内容……!即,未定义的行为,就像动态分配的数组一样。
  • 当然,但你说这与主题无关。这就是我所反对的。我提供了一种可能导致崩溃的机制。
  • @David,因为越界写入数组会导致崩溃(以及许多其他不好的事情:未定义的行为!)无论数组是否动态分配,说动态分配是正确的数组的性质与它无关。根据普通的亚里士多德逻辑,“无论 Y 是否存在,X 都可能发生”的陈述等同于“Y 的存在与 X 的发生无关”的陈述。
  • 啊,抱歉,我误读了您提到的“Q 的主题”。
【解决方案3】:

2个元素的数组的索引是array[0]和array[1],所以改成:

output[0] = unsigned int(inputInteger + 2209032000);
output[1] = unsigned int(inputFrac * 2e32);

【讨论】:

    【解决方案4】:

    使用output[0] 和output[1],C/C++ 数组是基于 0 的

    【讨论】:

      【解决方案5】:

      C++ 中的数组是从零开始的,因此大小为 2 的数组的元素是 output[0] 和 output[1]

      您可能还希望返回更能代表您正在返回的数据的内容,例如具有 seconds 和 fractional_seconds 成员的结构,而不是创建新数组。

      你在做的事情也有点奇怪——2209032000 是 70 年的秒数,将 short 乘以 2e32 的结果会溢出 unsigned int 的大小。

      【讨论】:

        【解决方案6】:

        以 C 风格编写此类函数的更常用方法是传入对将要设置的变量的引用。

        为方便起见,您可以返回输出缓冲区,以便函数可以轻松地在表达式中使用。

        unsigned int* convertTime(unsigned int* output, unsigned int inputInteger, unsigned short inputFrac) {
          double messageTimeFraction = double(inputFrac) * 20e-6;
        
          output[0] = unsigned int(inputInteger + 2209032000);
          output[1] = unsigned int(inputFrac * 2e32);
        
          return output; // Seconds
        }
        
        // later
        unsigned int seconds[2];
        unsigned int* pseconds;
        pseconds = convertTime(seconds,a,b);
        

        【讨论】:

          【解决方案7】:

          我为各种格式创建了时间结构,并编写了转换器函数来处理转换。通过使用结构,我不必担心内存泄漏和提高可读性。此外,代码现在比使用动态数组更具可扩展性,因为我可以添加更多字段并创建新的时间格式。

          struct time{
              unsigned int timeInteger;
              unsigned int timeFraction;
          }time_X, time_Y;
          

          我的愚蠢错误是从零开始索引的错字,但更大的错误是使用动态数组。

          【讨论】:

            猜你喜欢
            • 2015-01-11
            • 1970-01-01
            • 2016-01-12
            • 2012-12-16
            • 2016-04-21
            • 2021-02-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多