gpt4 book ai didi

c++ - 为什么访问从堆上的对象返回的 c_str 得到垃圾值?

转载 作者:行者123 更新时间:2023-12-05 06:51:51 25 4
gpt4 key购买 nike

有时我需要从 C 调用 C++ 对象。经过一些搜索,我知道我可以使用 extern "C" 来包装一些可以从 C 调用的接口(interface)。这是我的代码:

#include <iostream>
#include <string>

class Dog
{
public:
Dog(std::string nm = "Eddie"): name(nm), sound("woof")
{
std::cout << "Dog " << name << " is coming." << std::endl;
}
~Dog()
{
std::cout << "Dog " << name << " ran way." << std::endl;
}
std::string bark()
{
return sound;
}
private:
std::string name;
std::string sound;
};

extern "C" {
void * dog_come();
void dog_delete(void *);
const char * dog_bark(void *);
}

void * dog_come()
{
return new Dog();
}

void dog_go(void *pd)
{
delete (Dog *)pd;
}

const char * dog_bark(void *pd)
{
Dog *pdog = (Dog *)pd;
return pdog->bark().c_str();
}

int main(int argc, char *argv[])
{
Dog hobo("Hobo");
std::cout << hobo.bark() << std::endl;

void *eddie = dog_come();
std::cout << dog_bark(eddie) << std::endl;
dog_go(eddie);

return 0;
}

执行以下命令后:

g++ -std=c++11 main.cpp
./a.out

我认为输出应该是:

Dog Hobo is coming.
woof
Dog Eddie is coming.
woof
Dog Eddie ran way.
Dog Hobo ran way.

然而,我得到的真实输出是:

Dog Hobo  is coming.
woof
Dog Eddie is coming.
$%^& /**< garbage here */
Dog Eddie ran way.
Dog Hobo ran way.

谁能告诉我为什么?

最佳答案

最好的解决办法是修改代码如下:

   std::string bark() { return sound; }

进入

   const std::string& bark() { return sound; }

这同样会导致正确的执行和正确的代码。

但是,如果您想坚持使用原始代码中提供的方法并只解决问题,这里有一个替代方案。

当你调用你的函数时:

const char * dog_bark(void *pd)
{
Dog *pdog = (Dog *)pd;
return pdog->bark().c_str();
}

您的代码 return pdog->bark().c_str(); 执行以下操作:

  • std::string tmp(pdog->bark()) 一旦您退出函数,它就会被销毁。
  • tmp.c_str();只要不跳出函数就有效。但是当你出去的时候,这就变成了一个悬挂指针

另一种方法是声明一个全局缓冲区(char* buffer),dog_bark()main() 可以访问它的分配及其解除分配

您可以根据需要使用此缓冲区来传输指针(但您必须先分配它)并在使用后将其删除。

这里是我的提议,我只放修改后的代码:

char * buffer = NULL;

const char* dog_bark(void *pd)
{
Dog *pdog = (Dog *)pd;
//allocate a buffer of the same length as the string to convert
buffer = (char*)malloc( pdog->bark().length()*sizeof(char));
// copy the value of the string into the buffer
strcpy(buffer, pdog->bark().c_str());
//return the buffer
return buffer;
}

int main(int argc, char *argv[])
{

Dog hobo("Hobo");
std::cout << hobo.bark() << std::endl;

void *eddie = dog_come();
std::cout << dog_bark(eddie) << std::endl;
dog_go(eddie);
//free the buffer
free(buffer);
return 0;
}

执行会如您所愿。

关于c++ - 为什么访问从堆上的对象返回的 c_str 得到垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66061251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com