引用向量 [英] reference to a vector

查看:69
本文介绍了引用向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在仔细阅读来源,在

制作中非常坦率地看起来像是一场灾难。这是一个案例,虽然参考的回报变得混乱

我的理解基于读数。


struct bar {

double变量;

void init(){memset(this,0,sizeof(bar)); }

bar(){init(); }

bool运算符<(bar& f)const

{return(变量> f.variable); }

};


std :: vector<酒吧&& run_it()

{

std :: vector< bar> * ptr_f = new std :: vector< bar> ;;

bar f;


f.variable = 99。

ptr_f-> push_back(f);

返回(* ptr_f);

}


//稍后

int main()

{

std :: vector< bar> f = run_it();

std :: cout<< f.size()<< std :: endl;

std :: cout<< f [0]。变量<< std :: endl;


}

对于初学者来说,memset似乎假设bar是一个pod

类型并且它不是,但除此之外我的问题是:

run_it中分配的向量是通过引用本地

变量f返回的。我认为虽然说明引用(即

临时返回变量)已被重新安装并复制到f是安全的。这个

表示已分配内存的位置已丢失。如果我的

评估是正确的。我很惊讶编译器(.NET)允许我

重置(正确的术语?)参考?更令人惊讶的是我

得到了正确的答案(99)。


我认为

const std :: vector< BAR>&安培; f = run_it();

会更加谨慎,现在是清理的责任。


感谢您的澄清。 。

解决方案

ma740988写道:

我正在仔细阅读来源,坦率地看起来像是一场灾难在
制作中。这是一个案例,虽然我的理解基于读数,参考回报变得混乱。

结构栏{
双变量;
void init(){memset (这,0,sizeof(bar)); }
bar(){init(); }
bool operator<(bar& f)const
{return(变量> f.variable); }
};

std :: vector<酒吧&& run_it()
{
std :: vector< bar> * ptr_f = new std :: vector< bar> ;;
bar f;

f.variable = 99。
ptr_f-> push_back(f);
return(* ptr_f);
}
//稍后
int main()
{
std :: vector< bar> f = run_it();
std :: cout<< f.size()<< std :: endl;
std :: cout<< f [0]。变量<< std :: endl;

}对于初学者来说,memset似乎假设bar是一个pod
类型而且它不是,


同意。它太可怕了,很可能是UB。


但除此之外我的问题是:run_it中分配的向量是通过引用本地
变量f返回的。我认为虽然说明引用(即
临时返回变量)已经重新安装并复制到f是安全的。




否,ptr_f是指向从免费商店分配的内存的指针。当run_it()退出时,

内存不会消失,run_it会返回对免费商店中分配的向量的

引用。问题是

内存泄漏 - 没有办法删除新的矢量。


>> ; struct bar {

double variable;
void init(){memset(this,0,sizeof(bar)); }
bar(){init(); }
bool operator<(bar& f)const
{return(变量> f.variable); }
};

std :: vector<酒吧&& run_it()
{
std :: vector< bar> * ptr_f = new std :: vector< bar> ;;
bar f;

f.variable = 99。
ptr_f-> push_back(f);
return(* ptr_f);
}
//稍后
int main()
{
std :: vector< bar> f = run_it();
std :: cout<< f.size()<< std :: endl;
std :: cout<< f [0]。变量<< std :: endl;

}对于初学者来说,memset似乎假设bar是一个pod
类型而且它不是,



内存布局很可能与双倍相同,因此设置它。

具有相同的memsetting double效果。

同意。这太可怕了,很可能是UB。


我不这么认为。我认为这只是一个简单的问题

复杂但行为仍然很明确(但依赖于平台。)


这个定义本来可以是简单的以下:


结构栏{

双变量;

bar():变量(0.0){}

bool运算符<(bar& f)const {

返回变量> f.variable;

}

};

不,ptr_f是指向免费商店分配的内存的指针。当run_it()退出时,
内存不会消失,run_it会返回对免费商店中分配的向量的
引用。问题是内存泄漏 - 没有办法删除新的矢量。




我同意你的看法OP'代码中的内存泄露。但是,删除那个内存是可能的。只需


删除& f;


问候,

Ben




" benben" <是****** @ yahoo.com.au> skrev i meddelandet

news:44 *********************** @ news.optusnet.com.a u ... < blockquote class =post_quotes>

struct bar {
double variable;
void init(){memset(this,0,sizeof(酒吧)); }
bar(){init(); }
bool operator<(bar& f)const
{return(变量> f.variable);对于初学者来说,memset似乎假设bar是一个
pod
类型而且它不是,


内存布局很可能与双倍相同,所以memsetting
它具有相同的memsetting double效果。




但你不要不确定,因为结构不是POD。结构具有构造函数的事实

使得它成为非POD,并且从任何使用memset本身取消资格



同意。这太可怕了,很可能是UB。
我不是那么看的。我认为这只是一个简单的问题,但是行为仍然很明确(但平台依赖。)




另一个问题是代码假设double 0.0与char 0具有相同的位模式。这也不能保证。

定义可能是以下几点:

结构栏{
双变量;
bar():变量(0.0){}
bool运算符<(bar& f)const {
返回变量> f.variable;
}
};




好​​多了!

Bo Persson


I''m perusing source that quite frankly looks like a disaster in the
making. This is a case though where return by reference gets muddled
with my understand based on readings.

struct bar {
double variable;
void init() { memset ( this, 0, sizeof ( bar ) ); }
bar() { init(); }
bool operator <( bar & f ) const
{ return ( variable > f.variable ) ; }
};

std::vector< bar >& run_it ()
{
std::vector< bar > *ptr_f = new std::vector<bar >;
bar f;

f.variable = 99.;
ptr_f->push_back ( f );
return ( *ptr_f );
}

// later
int main()
{
std::vector<bar > f = run_it();
std::cout << f.size() << std::endl;
std::cout << f[ 0 ].variable << std::endl;

}
For starters, the memset seems to make an assumption that bar is a pod
type and it''s not, but that aside my question is this:
The vector allocated in run_it is returned by reference to the local
variable f. I think though it''s safe to state that the reference (i.e
temporary returned variable) has been reseated and copied to f. This
means the location of the allocated memory has been lost. If my
assessment is correct. I''m surpised the compiler (.NET) allowed me to
reseat ( right terminology ? ) the reference? Even more suprising is I
got the right answer ( 99 ).

I would think
const std::vector<bar>& f = run_it();
would be more prudent and it''s now f''s responsibility to clean up.

Thanks for the clarification..

解决方案

ma740988 wrote:

I''m perusing source that quite frankly looks like a disaster in the
making. This is a case though where return by reference gets muddled
with my understand based on readings.

struct bar {
double variable;
void init() { memset ( this, 0, sizeof ( bar ) ); }
bar() { init(); }
bool operator <( bar & f ) const
{ return ( variable > f.variable ) ; }
};

std::vector< bar >& run_it ()
{
std::vector< bar > *ptr_f = new std::vector<bar >;
bar f;

f.variable = 99.;
ptr_f->push_back ( f );
return ( *ptr_f );
}

// later
int main()
{
std::vector<bar > f = run_it();
std::cout << f.size() << std::endl;
std::cout << f[ 0 ].variable << std::endl;

}
For starters, the memset seems to make an assumption that bar is a pod
type and it''s not,
Agreed. It''s horrible, and quite possibly UB.

but that aside my question is this: The vector allocated in run_it is returned by reference to the local
variable f. I think though it''s safe to state that the reference (i.e
temporary returned variable) has been reseated and copied to f.



No, ptr_f is a pointer to memory allocated from the free store. The
memory doesn''t go away when run_it() exits, and run_it returns a
reference to the vector allocated on the free store. The problem is
that the memory leaks -- there''s no way to delete the new''ed vector.


>> struct bar {

double variable;
void init() { memset ( this, 0, sizeof ( bar ) ); }
bar() { init(); }
bool operator <( bar & f ) const
{ return ( variable > f.variable ) ; }
};

std::vector< bar >& run_it ()
{
std::vector< bar > *ptr_f = new std::vector<bar >;
bar f;

f.variable = 99.;
ptr_f->push_back ( f );
return ( *ptr_f );
}

// later
int main()
{
std::vector<bar > f = run_it();
std::cout << f.size() << std::endl;
std::cout << f[ 0 ].variable << std::endl;

}
For starters, the memset seems to make an assumption that bar is a pod
type and it''s not,


The memory layout is most likely the same as a double so memsetting it
has the same effect of memsetting a double.

Agreed. It''s horrible, and quite possibly UB.
I don''t see it that way. I think it is just a simple matter made
complicated but the behavior is still well defined (but platform dependent.)

The definition could have been trivially the following:

struct bar {
double variable;
bar():variable(0.0){}
bool operator <( bar & f) const{
return variable > f.variable;
}
};
No, ptr_f is a pointer to memory allocated from the free store. The
memory doesn''t go away when run_it() exits, and run_it returns a
reference to the vector allocated on the free store. The problem is
that the memory leaks -- there''s no way to delete the new''ed vector.



I agree with you that the memory in OP''s code is leaked. But it is
possible, though, to delete that memory. Simply

delete &f;

Regards,
Ben



"benben" <be******@yahoo.com.au> skrev i meddelandet
news:44***********************@news.optusnet.com.a u...

struct bar {
double variable;
void init() { memset ( this, 0, sizeof ( bar ) ); }
bar() { init(); }
bool operator <( bar & f ) const
{ return ( variable > f.variable ) ; }
};

For starters, the memset seems to make an assumption that bar is a
pod
type and it''s not,


The memory layout is most likely the same as a double so memsetting
it has the same effect of memsetting a double.



But you don''t know for sure, because the struct is not a POD. The fact
that the struct has a constructor makes it a non-POD, and disqualifies
it from any use of memset on itself.


Agreed. It''s horrible, and quite possibly UB.
I don''t see it that way. I think it is just a simple matter made
complicated but the behavior is still well defined (but platform
dependent.)



The other problem is that the code assumes that double 0.0 has the
same bit pattern as char 0. This is not guaranteed either.

The definition could have been trivially the following:

struct bar {
double variable;
bar():variable(0.0){}
bool operator <( bar & f) const{
return variable > f.variable;
}
};



Much better!
Bo Persson


这篇关于引用向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆