无法通过指针分配内存

时间:2020-03-01 19:00:04

标签: c++ pointers memory-management

我写了这个函数,其目的是结合等价的字符 参数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;
  }

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

正如@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的指针的大小)