将动态分配的内存从C++返回到C.

Fir*_*cer 2 c c++ memory-management

我有一个必须可以从C等使用的DLL,所以我不能正常使用字符串对象等,但我不知道如何安全地做到这一点..

const char *GetString()
{
    std::stringstream ss;
    ss << "The random number is: " << rand();
    return ss.str().c_str();
}
Run Code Online (Sandbox Code Playgroud)

当ss从堆栈上掉下来时,c字符串会被破坏吗?我这么假装......

另一种选择可能是在堆上创建一个新的字符串,但是要解除分配的是什么?

const char *GetString()
{
    std::stringstream ss;
    ss << "The random number is: " << rand();
    char *out = new char[ss.str().size()];
    strcpy(ss.str().c_str(), out);
    return out;//is out ever deleted?
}
Run Code Online (Sandbox Code Playgroud)

指向其他东西以及字符串的指针也是如此.

n-a*_*der 8

第一个变体不起作用,因为您将指针返回到堆栈对象,这将被销毁.(更确切地说,你返回一个指向堆内存的指针,它将被删除().)更糟糕的是,它甚至可能工作一段时间,如果没有人覆盖内存,使得调试非常困难.

接下来,除非返回指向静态字符串的指针,否则不能返回const char*:

const char *GetString()
{
    return "a static string in DATA segment - no need to delete";
}
Run Code Online (Sandbox Code Playgroud)

第二种变体的问题是将使用new()分配的内存返回到将调用free()的C程序中.那些可能不兼容.

如果将字符串返回给C,则有两种方法可以:

char *GetString()
{
    std::stringstream ss;
    ss << "The random number is: " << rand();
    return strdup( ss.str().c_str() ); // allocated in C style with malloc()
}

void foo()
{
    char *p = GetString();
    printf("string: %s", p));
    free( p ); // must not forget to free(), must not use delete()
}
Run Code Online (Sandbox Code Playgroud)

要么:

char *GetString(char *buffer, size_t len)
{
    std::stringstream ss;
    ss << "The random number is: " << rand();
    return strncpy(buffer, ss.str().c_str(), len); // caller allocates memory
}

void foo()
{
    char buffer[ 100 ];
    printf("string: %s", GetString(buffer, sizeof( buffer ))); // no memory leaks
}
Run Code Online (Sandbox Code Playgroud)

取决于你的记忆处理政策.

通常,您不能在C++中返回指针或对自动对象的引用.这是许多C++书籍中常见的错误之一.