1

当我编写这样的代码时,我遇到了一些 valgrind 问题:

static std::string function(std::string test)
{
        size_t pos = test.find(',');
        if (pos == test.npos)
        {
            // no comma
            //
            pos = test.length();
        }

        return test.substr(0, pos); //Valgrind is reporting possibly lost bytes here

}

现在我的问题是我应该这样做吗?

static std::string function(std::string test)
{
        size_t pos = test.find(',');
        if (pos == test.npos)
        {
            // no comma
            //
            pos = test.length();
        }
        static std::string temp = test.substr(0, pos);
        return temp;

}

我认为拥有字符串tempstatic 有点重要,因为function它是静态的,因此返回的任何内容都function应该与封装的对象具有相同的生命周期function。还是我的分析有问题?

谢谢

4

4 回答 4

2

我有一些 valgrind 问题

确切地!那是 Valgrind 的问题,而不是您的代码问题。Valgrind 并不总是正确的,在这种情况下,它会给你带来错误的警报。忽略它。

现在我的问题是我应该这样做吗?

不,静态函数和静态变量是两个不同的东西。此外,第二版代码在多线程环境中引入了可能的问题。

于 2013-01-31T19:22:03.247 回答
2

不要那样做,你会失去线程安全。第一个功能很好,没有内存泄漏。你创建了一个std::string临时的,但没关系,不用担心,它完美地处理分配的内存。您必须仔细阅读 valgrind 警告: I's a warning,并且valgrind认为它可能丢失了字节。现在可以去向自己保证没有任何损失。IIRC 有可能告诉 valgrind 这次一切正常。

于 2013-01-31T19:27:37.503 回答
2

现在我的问题是我应该这样做吗?

不,绝对不是。无需创建这样一个临时的(尤其不是static一个,使该功能不可重入,或者最终仅在您的情况下第一次工作)。我猜Valgrind在这里报告垃圾。您的代码看起来不错。

还是我的分析有问题?

是的。类static方法没有与之关联的对象,无论如何,它可能具有不同的生命周期(它就像一个普通的非类函数,只是你需要在调用时使用类名来限定它的范围)。除此之外,string无论如何您都不会返回对任何临时对象的引用,而是从 复制的新对象temp,因此这里没有要考虑的生命周期问题。

除此之外,您可能需要考虑test通过 const-reference 获取对象,因为您不修改也不复制它(这可能与对对象身份和对象值的一般误解有关吗?)。

于 2013-01-31T19:27:47.417 回答
2

第一个片段很好;第二个片段绝对不行(它只保证在你第一次使用它时能正常工作)。

其他人似乎都在告诉你忽略 Valgrind。不要那样做。您还没有向我们展示您的其余代码,很可能其他地方存在仅在此处表现出来的问题。

第二种选择是您的 C++ 库正在做一些古怪的事情,这会不必要地触发 Valgrind。如果是这样,那么解决方案是使用抑制文件。但是只有当你100%确定这是图书馆的问题时,你才应该这样做;否则,您将来会为误报做好准备。

于 2013-01-31T19:35:08.560 回答