无法使用构造函数为类函数赋值

not able to assign value to class function using constructor

本文关键字:类函数 赋值 构造函数      更新时间:2023-10-16

我在为类函数赋值时遇到问题。 我正在尝试使用 dqr 构造函数分配值,但值没有传递给类 dqr 的构建成员函数。 它显示的错误是分段错误。

class dqr{
int block_size;
int *blocks;
public:  
dqr(int input[], int);   
void build(int input[], int n);
void update(int input[],int,int , int);
};
dqr::dqr(int input[], int n){
int block_size=(sqrt(n));
cout<<"block Size :"<<block_size;
int *blocks=new int[block_size];
} 
void dqr::build(int input[], int n ){
for(int i=0;i<(n-1);i++){
blocks[i/block_size]+=input[i];}
for(int i=0;i<block_size;i++){
cout<<blocks[i];
} }
int main() 
{
int input[] = {1, 5, 2, 4, 6, 1, 3, 5, 7, 10};
int n = sizeof(input)/sizeof(input[0]);
dqr d(input, n);
d.build(input,n);
return 0; 
}

代码的主要问题是构造函数中的这一行:

int *blocks=new int[block_size];

指针int *blocks与成员指针int *blocks不同。发生的情况是,您在构造函数中创建一个名为blocks的本地指针,一旦您离开构造函数的范围,该指针就会死亡。遗憾的是,您已经在该本地指针指向的堆中分配了内存。但是当本地指针死亡并且您有泄漏时,不会释放此内存。

您对int block_size也有同样的问题,您也可以在构造函数中重新创建为局部变量。

构造函数应如下所示:

dqr(int input[], int n)
{
block_size = sqrt(n); //using the member variable block_size.
std::cout<< "block Size :" << block_size <<std::endl;
blocks = new int[block_size]; //using the member pointer blocks.
}

我仍然不太确定为什么你会得到n的平方根作为你的新块大小,但我想这是你设计的一部分。

另外不要忘记清除析构函数中的内存。事实上,这就是我们使用智能指针的原因。在您的情况下,unique_ptr将是最佳选择。

示例代码:https://rextester.com/CGFQQ92378

分段错误的原因在下面的代码中。

dqr::dqr(int input[], int n){
int block_size=(sqrt(n));
cout<<"block Size :"<<block_size;
int *blocks=new int[block_size];
} 

块变量声明为局部变量。 所以在构建函数的块变量中未在堆内存中分配(动态分配)。

由于您使用的是 GCC 编译器进行C++,因此有一个编译器选项会在您有一个隐藏类变量的声明局部变量时向您发出警告。这是-Wshadow.

使用此选项进行编译会给出以下警告:

warning: declaration of 'block_size' shadows a member of 'dqr' [-Wshadow]    
int block_size=(sqrt(n));    
^~~~~~~~~~
<source>:7:9: note: shadowed declaration is here    
int block_size;    
^~~~~~~~~~
<source>:19:15: warning: declaration of 'blocks' shadows a member of 'dqr' [-Wshadow]    
int* blocks=new int[block_size];    
^~~~~~
<source>:8:10: note: shadowed declaration is here
int *blocks;
^~~~~~

请参阅演示

从上面的警告中,您将知道您必须替换上述两行并通过以下方式实际初始化类变量:

block_size = (sqrt(n));
blocks = new int[block_size];