无法通过指针分配内存

问题描述 投票:0回答:2

我编写了此函数,其目的是将与参数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
2个回答
1
投票

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

  • 在函数中使用指针输出的副本(例如输出副本
  • 如果您使output_copy指向一些不同的数据/内存,则您的[[output指针仍指向其先前的数据/内存,
  • 退出函数后,您期望的修改没有发生(但这是正确的,因为数据/内存
  • 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的指针的大小)

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; }

© www.soinside.com 2019 - 2024. All rights reserved.