从函数返回QString-线程安全? 我是QT新手,但这可能是一个非常基础的C++问题。我有一个返回QString的简单函数: QString testclass::myfunc(int i) { QString result; switch (i) { case 1: result = "one"; break; case 2: result = "two"; break; } return result; }
这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?) QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串) 如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void)从函数返回QString-线程安全? 我是QT新手,但这可能是一个非常基础的C++问题。我有一个返回QString的简单函数: QString testclass::myfunc(int i) { QString result; switch (i) { case 1: result = "one"; break; case 2: result = "two"; break; } return result; },c++,qt,function,return-value,qstring,C++,Qt,Function,Return Value,Qstring,这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?) QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串) 如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void) 这是实际的函数(清理了一点)-请注意,如果出
这是实际的函数(清理了一点)-请注意,如果出现差异,此函数是静态的:
QString L::toString(const L::editions &level)
{
QString levelStr;
switch (level) {
case L::one:
levelStr = "one";
break;
case L::two:
levelStr = "two";
break;
case L::three:
levelStr = "thre";
break;
default:
levelStr = "Internal Error";
break;
}
return levelStr;
}
然而valgrind抱怨(第121行是“levelStr=”一“)
1个块中的34个字节肯定会在716的丢失记录197中丢失
在/mnt/lserver2/data/development/haast/src/linfo.cpp:121中的L::toString(L::edition const&;)中
1:malloc in/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
2:QArrayData::allocate(unsigned long、unsigned long、unsigned long、QFlagsQArrayData::AllocationOption)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
3:QString::QString(int,Qt::Initialization)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
4:/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
5:QString::fromUtf8_helper(char const*,int)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
6:QString::fromUtf8(字符常量*,int)在
7:QString::operator=(char const*)在
8:L::toString(L::Lconst&;)in
QString类提供Unicode字符串
QString存储一个16位QChar字符串,其中每个QChar对应
一个Unicode 4.0字符。(具有上述代码值的Unicode字符)
65535使用代理项对存储,即两个连续的QCHAR。)
Unicode是一种支持大多数书写的国际标准
目前正在使用的系统。它是US-ASCII(ANSI X3.4-1986)的超集
和拉丁语-1(ISO 8859-1),所有US-ASCII/拉丁语-1字符均为
在相同的代码位置可用
在幕后,QString使用隐式共享(写时复制)来
减少内存使用,避免不必要的数据复制。这
还有助于减少存储16位字符的固有开销
而不是8位字符
除了QString之外,Qt还提供了要存储的QByteArray类
原始字节和传统的以8位“\0”结尾的字符串。对大多数人来说
在这里,QString是您想要使用的类。它贯穿始终
QtaPI和Unicode支持确保您的应用程序
如果您想扩展应用程序的
市场在某一点。QByteArray所在的两种主要情况
当您需要存储原始二进制数据时,以及
内存保护非常关键(就像在嵌入式系统中一样)
基本上QString是非常棒的,几乎不用担心。你可以在任何地方使用它,不管你喜欢什么。如果经常追加字符串会导致速度减慢,有一种特殊的方法可以使用字符串生成器,但根据我的经验,在尝试改进QString之前,还有很多地方需要改进
直接回答您的问题:
这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?)
在上述所有情况下,它都是安全的。只要任何函数都有QString的句柄,共享指针等都会将其保存在内存中。一旦它完全超出范围,它就会自我清理
QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串)
不,没关系
如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void)
您应该使用跨线程保护来包装它,例如QMutexLocker
更新:QMutexLocker示例
// In your constructor
m_mutex = new QMutex();
// When accessing a shared element across threads
{
QMutexLocker locker(m_mutex);
// Accessing a variable is now threadsafe!
m_sharedDataString += "!";
}
希望对您有所帮助。QString
是一个值类,如果您无法从函数返回它,它将是无用的。这与std::string
没有什么不同。两者都可以按照您演示的方式使用
您提到的“常量字符串”的概念是虚构的。没有这样的事。语句result=“foo”代码>不会生成某种特殊的字符串。这不是C,您没有返回一个常量char*
——这是有充分理由的
线程安全方面与字符串没有多大关系。显示的方法体可以是静态方法,因为它不使用任何实例数据。它也是一个纯函数,根本无法访问任何共享状态。从定义上讲,这样的纯函数是线程安全的,因为它们不访问共享状态。您可能希望用一个更接近您的问题的示例来修改您的问题,并实际演示一些线程问题
QString
与其他Qt的隐式共享值类一样,只要只从一个线程访问它的特定实例,它就是线程安全的。实例是否从另一个字符串实例分配或复制并不重要。例如:
QString a = "foo";
{
QFutureSynchronizer sync;
sync.addFuture(QtConcurrent::run([&a] { a.append("bar"); }));
sync.addFuture(QtConcurrent::run([&a] { a.append("baz"); }));
}
// This is not thread safe: a might be concurrently accessed from two
// threads. The behavior is undefined. It might format your hard drive.
QString c = "Homer";
QString d = c;
{
QFutureSynchronizer sync;
sync.addFuture(QtConcurrent::run([&c] { c.append("'s"); }));
sync.addFuture(QtConcurrent::run([&d] { d.append(" and Elmer's"; }));
}
// This is thread safe. One of the threads will safely deep-copy the
// c's contents.
Q_ASSERT(c == "Homer's");
Q_ASSERT(d == "Homer and Elmer's");
这个函数返回对象(不是对象上的指针),所以它是安全的(因为有一个QString的复制构造函数,它会将局部变量result
的内容复制到调用者的外部变量中),我想是这样的。。。。
QString a = "foo";
{
QFutureSynchronizer sync;
sync.addFuture(QtConcurrent::run([&a] { a.append("bar"); }));
sync.addFuture(QtConcurrent::run([&a] { a.append("baz"); }));
}
// This is not thread safe: a might be concurrently accessed from two
// threads. The behavior is undefined. It might format your hard drive.
QString c = "Homer";
QString d = c;
{
QFutureSynchronizer sync;
sync.addFuture(QtConcurrent::run([&c] { c.append("'s"); }));
sync.addFuture(QtConcurrent::run([&d] { d.append(" and Elmer's"; }));
}
// This is thread safe. One of the threads will safely deep-copy the
// c's contents.
Q_ASSERT(c == "Homer's");
Q_ASSERT(d == "Homer and Elmer's");