【问题标题】:Unable to allocate memory via pointer无法通过指针分配内存
【发布时间】:2020-06-14 03:34:46
【问题描述】:

我写了这个函数,其目的是结合字符等价物 参数 3,与参数 2。然后为参数 1 分配内存并返回它。基于插入到函数中的调试语句,一切似乎都是正确的,但它似乎在返回时释放了内存。为什么是这样?还是我错过了什么?

我不习惯在 mac 上编程,我无法让 gdb 工作,所以我有点盲目。

功能

bool BraviaIpCtrl::setVolume(char *output, const char *input, unsigned short value)
{
  bool success = false;
  output = nullptr;

  if(value <= 100)
  {
    int msgLen = 24;
    output = new char[msgLen];
    memset(output, 0, sizeof(*output));
    std::string numbers = std::to_string(value).c_str();
    size_t len = numbers.length();
    memcpy(output, input, msgLen);
    memcpy(output + (msgLen - 1) - len, numbers.c_str(), len);
    success = true;
  }
  return success;
}

测试函数调用

  char* test = nullptr;

  if(bc.setVolume(test, bc.bctl_volume_set, 43) && test != nullptr)
  {
    std::cout << *test << std::endl;
  }
  else
  {
    std::cout << "NOPE!!" << std::endl;
  }

【问题讨论】:

    标签: c++ pointers memory-management


    【解决方案1】:

    问题是您将指针变量传递给函数,并且像任何其他变量一样通过值传递,因此方法“setVolume”正在制作指针测试的本地副本并分配内存。调用测试方法无法看到这种变化。

    为什么不将方法实现改为返回数组的地址。

    char * BraviaIpCtrl::setVolume(const char *input, unsigned short value)
    {
      char*  output = NULL;
      if(value <= 100)
      {
        int msgLen = 24;
        output = new char[msgLen];
        memset(output, 0, sizeof(*output));
        std::string numbers = std::to_string(value).c_str();
        size_t len = numbers.length();
        memcpy(output, input, msgLen);
        memcpy(output + (msgLen - 1) - len, numbers.c_str(), len);
      }
      return output;
    }
    

    【讨论】:

      【解决方案2】:

      正如@mailtreyak 所指出的,您正在传递一个指向 char 的指针:

      • 在函数中使用了指针output(比如说output_copy)的副本,
      • 如果您让 output_copy 指向一些不同的数据/内存,您的 output 指针仍指向其先前的数据/内存,
      • 一旦您退出函数,您期望的修改就没有发生(但这是正确的,因为数据/内存输出指向根本没有被修改)。

      您可以在下面找到另一种使用 PointerToPointer (**) 的方法:

      bool BraviaIpCtrl::setVolume(char** output, const char* input, unsigned short value)
      {
          bool success = false;
          *output = nullptr;
      
          if (value <= 100)
          {
              int msgLen = 24;
              *output = new char[msgLen];
              memset(*output, 0, msgLen);
              std::string numbers(*output);
              size_t len = numbers.length();
              memcpy(*output, input, msgLen);
              memcpy(*output + (msgLen - 1) - len, numbers.c_str(), len);
              success = true;
          }
          return success;
      }
      

      和调用代码:

      char* test = nullptr;
      if (bc.setVolume(&test, bc.bctl_volume_set, 43) && test != nullptr)
      {
          std::cout << *test << std::endl;
      }
      else
      {
          std::cout << "NOPE!!" << std::endl;
      }
      

      请注意你之前代码中的这个错误:

      int msgLen = 24;
      output = new char[msgLen];
      memset(output, 0, sizeof(*output));
      

      应该改为:

      int msgLen = 24;
      output = new char[msgLen];
      memset(output, 0, msgLen);
      

      这是因为你想设置 24 个字节,而不仅仅是 1 个字节(1 = sizeof(*output),指向 char 的指针的大小)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-11
        • 2015-02-27
        • 2020-09-22
        • 1970-01-01
        • 1970-01-01
        • 2021-06-22
        • 2015-04-21
        • 1970-01-01
        相关资源
        最近更新 更多