επιστημηさん。
>「pccc++ する意味がなくなる」だけじゃね?
おお、その通りです。
ぴかりんさん、すみませんうそ書きました。
私の発言は無視してください。m(__)m
うーん、C++言語の勉強をちゃんとした方が良いのではと言う気が・・・。
newを使わないとコンスタラクタが動かないとかこの辺は入門書にも
書いてある話なので、一足飛びに使おうとしないで基礎を一通り勉強
されたほうが良いと思いますよ。
あと、ステップ・バイ・ステップで進めていくつもりなら
ソースを書くときもそれを考慮して書かないとへんな所ではまります。
今回の例から行くと複数の配列確保をどうするのかまで
考えきれて無いのにループにしてしまっている時点で既に問題かと。
みなさん 色々なご指摘ありがとうございます
もう一度基礎から見直してみることにします
ありがとうございました
これってこういうことじゃ?
typedef struct{
CString AAA;
CString BBB;
}CCC;
--------------------------------
void ddd()
{
ccc* pccc;
while(1)
{
pccc = (CCC*)malloc(sizeof(CCC));
pccc->AAA = new CString();
pccc->AAA = 1234
pccc++;
}
追加終わったら
delete pccc->AAA
free(pccc );
}
>これってこういうことじゃ?
>pccc->AAA = new CString();
AAA は CString*型でないですよ。
仮に、AAAがCString*型でも、今度はこっちがバグってますし。
pccc->AAA = 1234
ポインタの参照先を直接書き換えてるだけで、CString::operator =は動かない。
# 配置newとか駆使してごにょごにょとか考えるよりは、
# 素直にstd::vectorやC~Arrayの類を使うことを考えるという方向でよいと思います。
> ポインタの参照先を直接書き換えてるだけで
# 書き換えも無理やりキャストが必要。
失礼。ではこれではだめですか?
typedef struct{
CString* AAA;
CString* BBB;
}CCC;
--------------------------------
void ddd()
{
ccc* pccc;
while(1)
{
pccc = (CCC*)malloc(sizeof(CCC));
pccc->AAA = new CString();
*pccc->AAA = 1234
pccc++;
}
追加終わったら
delete pccc->AAA
free(pccc );
?
これならばOKですが、
元からCStringでもったCCCをmallocせず、newすればいいだけなのであまり意味ないので
は?
(いちいちmallocしてnewする意味あるのかなぁと)
ループの中でpcccを更新してしまったら、ループの後にいくら解放処理を書いても、
delete pccc->AAA
free(pccc );
最後のpcccしか解放できず他は全部リークすると思いますが。
> 動的配列使ったほうがよさげ。
> そうすればポインタなんて関係ないかと。
PODが必要ならCStringは諦めるしかないし、
Blueさんの提案どおりにこうにしない理由がよくわからず。
# 配置newってのは最後の手段だと思う…。
最終的にはこんな感じで使いたいわけではなく?
typedef struct{
CString* StrAdress;
CString* StrParent;
CString* StrName;
HTREEITEM item;
BOOL bRet;
}S_VIEW_DATA;
typedef struct{
S_VIEW_DATA* pdata;
long count;
}S_VIEW;
//********************************************************************
//
//
//
//********************************************************************
void CTabDlg::InPutFile(CString StrFileName)
{
//変数定義
S_VIEW s_view;
CString StrLine;
CString StrTemp;
long i,j;
long pos;
long setCount;
CStdioFile file;
CString StrAdress;
CString StrParent;
CString StrName;
//初期化処理
s_view.count = 0;
setCount = 0;
//----------------------------------
// 表示項目全削除
//----------------------------------
m_tree.DeleteAllItems();
//----------------------------------
// ファイル読み出し
//----------------------------------
file.Open(StrFileName,CFile::modeRead);
//----------------------------------
// 項目数取得
//----------------------------------
while(1)
{
file.ReadString(StrLine);
if(StrLine != ")
{
s_view.count++;
}
else
{
break;
}
}
file.Seek(0,0);
//----------------------------------
// データ領域取得
//----------------------------------
s_view.pdata = (S_VIEW_DATA*)malloc(sizeof(S_VIEW_DATA) *
s_view.count);
//----------------------------------
// データの読み取り
//----------------------------------
for(i = 0; i < s_view.count; i++)
{
s_view.pdata[i].StrAdress = new CString();
s_view.pdata[i].StrParent = new CString();
s_view.pdata[i].StrName = new CString();
s_view.pdata[i].bRet = FALSE;
file.ReadString(StrLine);
//1つ目
pos = StrLine.Find(,,0);
StrAdress = StrLine.Left(pos);
*s_view.pdata[i].StrAdress = StrAdress;
StrLine.Delete(0,pos+1);
//2つ目
pos = StrLine.Find(,,0);
StrParent = StrLine.Left(pos);
*s_view.pdata[i].StrParent = StrParent;
StrLine.Delete(0,pos+1);
//3つ目
StrName = StrLine.Left(StrLine.GetLength());
*s_view.pdata[i].StrName = StrName;
}
//----------------------------------
// 先頭ノードの設定
//----------------------------------
for(i = 0; i < s_view.count; i++)
{
if(*s_view.pdata[i].StrParent == 0x00000000)
{
s_view.pdata[i].item = m_tree.InsertItem
(*s_view.pdata[i].StrName,TVI_ROOT);
setCount++;
}
}
if(setCount != s_view.count)
{
while(1)
{
//--------------------------
// 子供ノードの設定
//--------------------------
for(i = 0; i < s_view.count; i++)
{
for(j = 0; j < s_view.count; j++)
{
if(*s_view.pdata[j].StrParent ==
*s_view.pdata[i].StrAdress)
{
s_view.pdata[j].item =
m_tree.InsertItem(*s_view.pdata[j].StrName,s_view.pdata[i].item);
setCount++;
if(setCount ==
s_view.count)
{
break;
}
}
}
}
if(setCount == s_view.count)
{
break;
}
}
}
//----------------------------------
// 領域開放
//----------------------------------
for(i = 0; i < s_view.count; i++)
{
delete s_view.pdata[i].StrAdress;
delete s_view.pdata[i].StrParent;
delete s_view.pdata[i].StrName;
}
free(s_view.pdata);
file.Close();
}
ですから、元からnewすれば構造体のメンバをポインタにする必要もないのですが。
struct S_VIEW_DATA
{
CString StrAdress;
CString StrParent;
CString StrName;
HTREEITEM item;
BOOL bRet;
};
//----------------------------------
// データ領域取得
//----------------------------------
s_view.pdata = new S_VIEW_DATA[s_view.count];
//----------------------------------
// 領域開放
//----------------------------------
delete [] s_view.pdata;
んでもって、MFCならCArray<S_VIEW_DATA, S_VIEW_DATA>を使うと便利。
(これなら前もってサイズを求めるために2度ファイルを読む必要がない)
そうなんですか?
それは知りませんでした。
ありがとうございます。
そんな使い方があったとは、知りませんでした。