首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么访问从堆上的对象返回的c_str会得到垃圾值?

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

Stack Overflow用户
提问于 2021-02-05 18:06:06
回答 1查看 156关注 0票数 3

有时我需要从C调用C++对象。经过一番搜索,我知道我可以使用

包装一些可以从C调用的接口,下面是我的代码:

代码语言:javascript
复制
#include 
#include 

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

之后执行以下命令:

代码语言:javascript
复制
g++ -std=c++11 main.cpp
./a.out

我认为输出应该是:

代码语言:javascript
复制
Dog Hobo is coming.
woof
Dog Eddie is coming.
woof
Dog Eddie ran way.
Dog Hobo ran way.

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

代码语言:javascript
复制
Dog Hobo  is coming.
woof
Dog Eddie  is coming.
$%^& /**< garbage here */
Dog Eddie ran way.
Dog Hobo ran way.

谁能告诉我为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-05 18:26:05

最好的解决方案是修改代码,如下所示:

代码语言:javascript
复制
std::string bark() { return sound; }

变成

代码语言:javascript
复制
const std::string& bark() { return sound; }

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

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

当你调用你的函数时:

代码语言:javascript
复制
const char * dog_bark(void *pd)
{
    Dog *pdog = (Dog *)pd; 
    return pdog->bark().c_str();
}

你写代码

执行以下操作:

一旦你走出函数,它就会被销毁。

只要你不走出函数,它就是有效的。但是当你出去的时候,这就变成了一个

另一种方法是声明一个全局缓冲区(

)

可以访问它的分配和它的

..。

您可以使用此缓冲区来传输您想要的指针(但您必须先分配它),并在使用它之后删除它。

这是我的建议,我只放了修改后的代码:

代码语言:javascript
复制
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;
}

执行完成了您想要的操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66061251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档