gpt4 book ai didi

c++ - 初始化列表中的 QString 导致访问冲突。这里出了什么问题?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:47:44 26 4
gpt4 key购买 nike

在我不理解的初始化列表中使用 QString 时,我遇到了访问冲突。

这是一个重现问题的最小示例。

// file ClassA.h
#pragma once
#include <QString>

struct Parameter
{
QString stringPar;
};

class ClassA
{
QString m_string1;

public:
void function(Parameter pars);
};

A 类的实现...

// file ClassA.cpp
#include "ClassA.h"

void ClassA::function(Parameter pars)
{
m_string1 = pars.stringPar; // last line called in my code when the crash happens
}

和main.cpp

// file main.cpp
#include "ClassA.h"

int main()
{
ClassA classA;

classA.function({ QString("jkjsdghdkjhgdjufgskhdbfgskzh") });

// when using this code the problem does not occur
//Parameter par = { QString("jkjsdghdkjhgdjufgskhdbfgskzh") };
//classA.function(par);

return 0;
}

违规时的调用栈:

Qt5Cored.dll!QGenericAtomicOps<QAtomicOpsBySize<4> >::load<long>(const long & _q_value) Line 96
Qt5Cored.dll!QBasicAtomicInteger<int>::load() Line 142
Qt5Cored.dll!QtPrivate::RefCount::ref() Line 57
Qt5Cored.dll!QString::operator=(const QString & other) Line 1355
EducationalCode.exe!ClassA::function(Parameter pars) Line 6
EducationalCode.exe!main() Line 8

ClassA::function() 中的复制赋值似乎出了点问题,但我不确定是什么问题。当我将函数签名更改为

function(const Parameter& pars);

它也不会崩溃。

你有什么想法吗?

最佳答案

你应该添加一个复制构造函数:

struct Parameter
{
QString stringPar;
Parameter& Parameter(const Parameter& rhs)
{
if((void*)this == (void*)&rhs)
{
return *this;
}
this->stringPar = rhs.stringPar;
return *this;
}
};

当您调用 ClassA::function() 时会创建一个临时参数实例,因为 C++ 按值传递参数;像这样:

void ClassA::function(Parameter pars = QString("jkjsdghdkjhgdjufgskhdbfgskzh"))
{
m_string1 = pars.stringPar; // last line called in my code when the crash happens
}

如果你不写拷贝构造函数,编译器会合成一个默认的拷贝构造函数,如下所示:

    Parameter& Parameter(const Parameter& rhs)
{
memcpy(this, &rhs, sizeof(Parameter));
return *this;
}

我猜想 QString 有指针成员,假设它的名字是 ptr。然后 pars.stringPar.ptr 和 QString("jkjsdghdkjhgdjufgskhdbfgskzh").stringPar.ptr 将指向相同的内存地址。

像这样调用函数:

 classA.function({ QString("jkjsdghdkjhgdjufgskhdbfgskzh") });

{ QString("jkjsdghdkjhgdjufgskhdbfgskzh") } 对象在 classA.function() 返回之前销毁,然后释放 {QString("jkjsdghdkjhgdjufgskhdbfgskzh")}.stringPar.ptr 指向的内存,和 pars.stringPar.ptr 指向无效内存。

// when using this code the problem does not occur
//Parameter par1 = { QString("jkjsdghdkjhgdjufgskhdbfgskzh") };
//classA.function(par1)
//par1 destroy when main() function return, thus classA.function() does not crash.

参见<<有效的C++>>第 11 条:为具有动态分配内存的类声明复制构造函数和赋值运算符。有效的 C++,2E http://debian.fmi.uni-sofia.bg/~mrpaff/Effective%20C++/EC/EI11_FR.HTM

关于c++ - 初始化列表中的 QString 导致访问冲突。这里出了什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149638/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com