我有一个必须可以从C等使用的DLL,所以我不能正常使用字符串对象等,但我不知道如何安全地做到这一点..
const char *GetString() { std::stringstream ss; ss << "The random number is: " << rand(); return ss.str().c_str(); }
当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? }
指向其他东西以及字符串的指针也是如此.
第一个变体不起作用,因为您将指针返回到堆栈对象,这将被销毁.(更确切地说,你返回一个指向堆内存的指针,它将被删除().)更糟糕的是,它甚至可能工作一段时间,如果没有人覆盖内存,使得调试非常困难.
接下来,除非返回指向静态字符串的指针,否则不能返回const char*:
const char *GetString() { return "a static string in DATA segment - no need to delete"; }
第二种变体的问题是将使用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() }
要么:
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 }
取决于你的记忆处理政策.
通常,您不能在C++中返回指针或对自动对象的引用.这是许多C++书籍中常见的错误之一.