由于我无法控制的原因,我需要从函数返回const char*
,但我不知道char
在编译时需要什么。我的解决方案如下:
const char* __str__() {
static std::string String;
String = [some fancy stuff];
return String.c_str();
}
static
可以防止字符串在退出函数时被破坏,但这也意味着内存会一直存在,直到我的程序退出(对吗?)。因为返回的字符串有时可能巨大(GB),这可能是一个真正的问题。
我通常会不惜一切代价避免使用指针,并且只对类成员使用static
,所以我不能100%确定我在做什么。这保证有效吗?还有更好的方法吗?
[这个问题的上下文是使用__str__
方法在python中打印一个复杂的对象。我在我的c ++代码中定义了该方法,然后由SWIG包装。 SWIG示例显示了static
的使用,但我不清楚这是唯一的方法。我愿意接受建议。]
答案 0 :(得分:10)
static
除分配范围外还会出现其他问题:
任何理由不返回该值并让调用者释放它?:
const char* __str__() {
char *s = malloc(2 * 1024 * 1024 * 1024); // 2 GB
[some fancy stuff with s];
return s;
}
...
const char *magic = __str__();
[do something with magic]
free (magic); magic = NULL; // all done
答案 1 :(得分:5)
正如@Prætorian所说,SWIG可以将std :: string返回给Python。以下是我认为您正在研究的SWIG示例中的示例。还显示了一种避免在C ++中使用保留名称的方法:
%module x
%{
#include "x.h"
%}
%include <windows.i>
%include <std_string.i>
%rename(__str__) display;
%include "x.h"
#include <sstream>
#include <string>
class Vector
{
public:
double x,y,z;
Vector(double a,double b,double c):x(a),y(b),z(c) {}
~Vector() {}
#ifdef SWIG
%extend {
std::string display()
{
std::ostringstream temp;
temp << '[' << $self->x << ',' << $self->y << ',' << $self->z << ']';
return temp.str();
}
}
#endif
};
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import x
>>> v = x.Vector(1.0,2.5,3.0)
>>> print v
[1,2.5,3]
答案 2 :(得分:3)
这保证可行,但有重要的警告。
所有警告归结为两个基本问题,这些问题以一种不太令人愉快的方式结合在一起:
String
的一个实例。String
不是常数。这会引起各种有趣的问题。例如,如果您在程序中的其他位置再次调用__str__
,则任何保存了您传回给它们的const char *
副本的人可能最终都会持有无效指针。即使它们不是,它们最终也会指向已经改变的记忆。简而言之,结果将是未定义的行为。
另一个例子,如果你从多个线程调用__str__
,它会在某个时刻爆炸,因为两个线程都试图同时修改String
。
幸运的是,您没有静态初始化顺序问题。保证String
在您第一次拨打__str__
时初始化。
如果您确定没有任何人String
指向该州,则可以通过String.clear()
中的__str__
来解决const char *
永远留在身边的问题您的String
。 String.clear()
将释放它可能正在使用的任何存储空间。
就个人而言,我只会将此作为最后的手段。程序的随机部分有可能使指针松散,这会让我无休止地担心。没有明确指示此指针的生命周期,除了在再次调用__str__
时无法保证工作的事实。但话又说回来,这可能取决于__str__
究竟是什么。
此外,__str__
是一个糟糕的名称。包含两个连续下划线的名称保留用于C ++实现。