随笔 - 505  文章 - 1034  trackbacks - 0
<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345


子曾经曰过:编程无他,唯手熟尔!

常用链接

留言簿(94)

随笔分类(649)

随笔档案(505)

相册

BCB

Crytek

  • crymod
  • Crytek's Offical Modding Portal

Game Industry

OGRE

other

Programmers

Qt

WOW Stuff

搜索

  •  

积分与排名

  • 积分 - 903797
  • 排名 - 14

最新随笔

最新评论

阅读排行榜

评论排行榜

c++ builder 6中就是改变不了元素的值,不会编译不过,执行也不报错。这玩意儿把我害惨了,害我找了好长时间。
有空测试下vc7.1,vc8和c++ builder 2007,gcc

写了个测试程序vc7.1下居然能改变值:
#include <vector>

struct stUpdateItem
{
    
bool _downloadSucceeded;

    stUpdateItem() : _downloadSucceeded(
false)
    {}
};

struct stDownItem
{
    stUpdateItem
* _pItem;
    
bool          _bPack;

    stDownItem(stUpdateItem
* item, bool bPack) : _pItem(item),_bPack(bPack)
    {}
};

typedef std::vector
<stDownItem> tDownItems;

int _tmain(int argc, _TCHAR* argv[])
{
    tDownItems downList;

    stUpdateItem item1;
    stUpdateItem item2;

    stDownItem downItem1(
&item1,true);
    stDownItem downItem2(
&item2,false);

    downList.push_back(downItem1);
    downList.push_back(downItem2);

    
for (tDownItems::const_iterator it = downList.begin(); it != downList.end(); ++it)
    {
        
if(true == it->_pItem->_downloadSucceeded)
        {
            std::cout 
<< "before change, found!" << std::endl;
        }
    }

    
for (tDownItems::const_iterator it = downList.begin(); it != downList.end(); ++it)
    {
        it
->_pItem->_downloadSucceeded = true;
    }

    
for (tDownItems::const_iterator it = downList.begin(); it != downList.end(); ++it)
    {
        
if(true == it->_pItem->_downloadSucceeded)
        {
            std::cout 
<< "after change, found!" << std::endl;
        }
    }
    
return 0;
}

执行结果:
after change, found!
after change, found
!
posted on 2007-10-31 12:12 七星重剑 阅读(1972) 评论(9)  编辑 收藏 引用 所属分类: PL--c/c++

FeedBack:
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 12:55 lovedday
....
能改变值是正常的,const_iterator限定的是stDownItem,而不是stUpdateItem,而你改变的是stUpdateItem的值,当然可以。

for (tDownItems::const_iterator it = downList.begin(); it != downList.end(); ++it)
{
it->_pItem->_downloadSucceeded = true;
}  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 13:42 lovedday
不过我可能会这么写:

#include <malloc.h>
#include <vector>

using namespace std;

typedef struct UPADTE_ITEM
{
bool down_succeeded;

UPADTE_ITEM()
{
down_succeeded = false;
}
} *UPADTE_ITEM_PTR;

typedef struct DOWN_ITEM
{
UPADTE_ITEM_PTR update_item;
bool pack;

DOWN_ITEM()
{
memset(this, 0, sizeof(*this));
}
} *DOWN_ITEM_PTR;

int main()
{
vector<DOWN_ITEM> down_item_vec;

UPADTE_ITEM item1;
UPADTE_ITEM item2;

DOWN_ITEM downItem1;
downItem1.update_item = &item1;
downItem1.pack = true;

DOWN_ITEM downItem2;
downItem2.update_item = &item2;
downItem2.pack = false;

down_item_vec.push_back(downItem1);
down_item_vec.push_back(downItem2);

for (vector<DOWN_ITEM>::const_iterator it = down_item_vec.begin(); it != down_item_vec.end(); ++it)
{
it->update_item->down_succeeded = true;
}

return 0;
}  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 13:46 lovedday
也可能这么写:

#include <stdio.h>
#include <malloc.h>

typedef struct UPDATE_ITEM
{
bool down_succeeded;
} *UPDATE_ITEM_PTR;

typedef struct DOWN_ITEM
{
UPDATE_ITEM_PTR update_item;
bool pack;

DOWN_ITEM* next;
} *DOWN_ITEM_PTR;

DOWN_ITEM_PTR create_down_item(bool pack, bool down_succeeded)
{
DOWN_ITEM_PTR down_item = (DOWN_ITEM_PTR) malloc(sizeof(DOWN_ITEM));
down_item->pack = pack;

down_item->update_item = (UPDATE_ITEM_PTR) malloc(sizeof(UPDATE_ITEM));
down_item->update_item->down_succeeded = down_succeeded;

down_item->next = NULL;

return down_item;
}

void free_all_down_item(DOWN_ITEM_PTR root_down_item)
{
DOWN_ITEM_PTR down_item_ptr = root_down_item;

while(down_item_ptr)
{
if(down_item_ptr->update_item)
free(down_item_ptr->update_item);

DOWN_ITEM_PTR temp_ptr = down_item_ptr;
down_item_ptr = down_item_ptr->next;

free(temp_ptr);
}
}

int main()
{
DOWN_ITEM_PTR down_item1 = create_down_item(true, false);
DOWN_ITEM_PTR down_item2 = create_down_item(false, false);

down_item1->next = down_item2;

DOWN_ITEM_PTR down_item_ptr = down_item1;

while(down_item_ptr)
{
down_item_ptr->update_item->down_succeeded = true;
down_item_ptr = down_item_ptr->next;
}

free_all_down_item(down_item1);

return 0;
}  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 15:20 lovedday
你的代码中涉及到内存的两次分配。

  stDownItem downItem1(&item1, true); // 第一次分配
stDownItem downItem2(&item2, false);

downList.push_back(downItem1); // 第二次分配
downList.push_back(downItem2);

---------------------------------------------------------------------------------------------------------

而C风格仅涉及到一次内存分配。

DOWN_ITEM_PTR down_item1 = create_down_item(true, false); // 就一次内存分配
DOWN_ITEM_PTR down_item2 = create_down_item(false, false);

down_item1->next = down_item2;
  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 15:27 lovedday
正确的做法应该是:

downList.push_back(stDownItem(&item1, true));
downList.push_back(stDownItem(&item2, false));
  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 15:34 lovedday
似乎也涉及到内存的两次分配,免不了了,STL的push_back必然需要拷贝一次原始对象,从这种意义上说,可以不用vector,哈哈。
  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-10-31 18:08 lovedday
我做了个试验,试验条件是XP + VS 2005,在Release版本下测试,结果相当令人吃惊。

malloc版本:

#define ITEM_TIMES 1000000

#include <malloc.h>

#define NULL 0

typedef struct UPDATE_ITEM
{
bool down_succeeded;
} *UPDATE_ITEM_PTR;

typedef struct DOWN_ITEM
{
UPDATE_ITEM_PTR update_item;
bool pack;

DOWN_ITEM* next;
} *DOWN_ITEM_PTR;

DOWN_ITEM_PTR create_down_item(bool pack, bool down_succeeded)
{
DOWN_ITEM_PTR down_item = (DOWN_ITEM_PTR) malloc(sizeof(DOWN_ITEM));
down_item->pack = pack;

down_item->update_item = (UPDATE_ITEM_PTR) malloc(sizeof(UPDATE_ITEM));
down_item->update_item->down_succeeded = down_succeeded;

down_item->next = NULL;

return down_item;
}

void free_all_down_item(DOWN_ITEM_PTR root_down_item)
{
DOWN_ITEM_PTR down_item_ptr = root_down_item;

while(down_item_ptr)
{
if(down_item_ptr->update_item)
free(down_item_ptr->update_item);

DOWN_ITEM_PTR temp_ptr = down_item_ptr;
down_item_ptr = down_item_ptr->next;

free(temp_ptr);
}
}

int main()
{
DOWN_ITEM_PTR first, last, ptr;

for(int i = 0; i < ITEM_TIMES; i++)
{
if(i == 0)
{
first = create_down_item(true, false);
last = first;
}
else
{
ptr = create_down_item(true, false);
last->next = ptr;

last = ptr;
}
}

while(1)
;

free_all_down_item(first);

return 0;
}

vector版本:

#include <vector>

using namespace std;

typedef struct UPADTE_ITEM
{
bool down_succeeded;

UPADTE_ITEM()
{
down_succeeded = false;
}
} *UPADTE_ITEM_PTR;

typedef struct DOWN_ITEM
{
UPADTE_ITEM_PTR update_item;
bool pack;

DOWN_ITEM()
{
update_item = NULL;
pack = false;
}

DOWN_ITEM(UPADTE_ITEM_PTR _update_item, bool _pack)
{
update_item = _update_item;
pack = _pack;
}
} *DOWN_ITEM_PTR;

int main()
{
vector<DOWN_ITEM> down_item_vec;

UPADTE_ITEM_PTR update_item_list = new UPADTE_ITEM[ITEM_TIMES];

for(int i = 0; i < ITEM_TIMES; i++)
down_item_vec.push_back(DOWN_ITEM(&update_item_list[i], true));

while(1)
;

delete[] update_item_list;

return 0;
}

改变ITEM_TIMES的值以改变迭代次数。

内存消耗比较:

迭代1000次: malloc - 868k vector - 796K
迭代10000次 : malloc - 1784k vector - 916k
迭代100000次 : malloc - 10956k vector - 2000k
迭代1000000次 : malloc - 102648k vector - 10008k

vector版本内存消耗更少,我想应该是多次malloc导致内存消耗剧增,而vector只在必要的时候才重新分配内存。
而malloc版本在代码中所涉及的指针操作也相当烦琐。
  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-11-01 15:11 重剑
@lovedday
呵呵,你真有空啊。居然回复了这么多。
受益匪浅,只是不喜欢c风格的代码。。。  回复  更多评论
  
# re: 用std::vector的const_iterator对元素赋值会怎样? 2007-11-01 19:04 lovedday
哈哈,献丑了。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理