• 締切済み

CObArrayの要素の削除

必要に応じて拡張した配列の要素を全削除します。 CTEST *p; Break-> for(i = 0; i < this->GetSize();; i++) { p = (CTEST*)this->GetAt(i); delete p; p = NULL; } this->RemoveAll(); 以上の様にしてみたのですが、デバックモードで削除を実行すると最後まで実行されずに?混合モードになります。 これはなにか悪い事でもしでかしているのでしょうか? できましたら、今回に限らずステップ実行から混合モードへ移ってします理由を教えていただけるとありがたいです。

みんなの回答

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.2

> 一旦勝手にブレイクするのは何故? ソースを適当に修正して実行してみましたが、私の環境(Win2000,VC++6.0sp?)だと再現しませんでした。 「ブレークポイントの設定位置 0x????」で止まるってのはあまり経験ないですが、「ブレークポイントの設定位置」のキーワードで情報収集すると、デバッグ中にそういう事が起こる例はあるようです。 メモリ破壊でブレークポイントの情報が壊れるってのも考え難いですね。 別の方向から、チェックする項目を上げてみると… 1) [編集]-[ブレークポイント]でブレークポイントが設定されていないか確認。 データの変化やメッセージを受け取った際にブレークする場合もあるので、そちらも確認。 [すべて削除]で一旦削除してみる。 2) ブレークした状態で、 [表示]-[デバッグウインドウ]-[コールスタック]を表示し、該当処理を呼び出した処理は?そのときの引数は?そのまた呼び出し元は?と辿ってみる。 -- > デバッグ情報が無いというのはどういう事ですか? 私の環境の例ですが、いきなり[デバッグ]-[ステップイン]を実行すると、 int WINAPI _tWinMain(…) の関数(Cの場合はmain関数など)が呼び出されます。 インストールの際の設定によりますが、_tWinMain関数の定義されている"appmodul.cpp"ファイルが無い場合や、ソースファイルがあってもexeとcppを関連付けているデバッグ情報が無い場合、プログラムの開始位置で止まっている状況を表示しなければならないが、ソースが分からないという事で、混合モードが表示されます。 動的にリンクしたライブラリの関数(ソースなし)にステップイン、printf関数にステップイン、などすると設定次第ですが混合モードが表示されるハズです。

donta01
質問者

お礼

>動的にリンクしたライブラリの関数(ソースなし)にステップイン、printf関数にステップイン、などすると設定次第ですが混合モードが表示されるハズです 回答ありがとうございました。なんとなく聞いた覚えがあるような・・・、って程度の認識しかありませんでした。

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.1

CTESTの宣言、該当処理のクラス宣言、関数宣言、など提示してもらわないと、なんとも…。 エラーメッセージなどは表示されないのですか? -- class CTEST {}; class CTESTary : public CObArray {public:void doo();}; void CTESTary::doo() {該当処理} void CTest1211Dlg::OnButton1() // 適当なダイアログ {CTESTary a;a.doo();} のようにすると、普通に実行されているようでしたが。 -- > ステップ実行から混合モードへ移ってします理由を教えていただけるとありがたいです。 基本的にはデバッグ情報が無い場合です。

donta01
質問者

補足

説明不足で申し訳ありません。 class CTEST : public CObArray { public: void Set(const AAA *); const AAA *Get(int); void Erase(void); private: void Sort(int(*Comp)(CObject *, CObject *),int, int); }; void CTEST::Set(const AAA *p) { AAA *c = new AAA; *c = *p); Add((CObject*)c); Sort(Comp, 0, GetUpperBound()); } const AAA* CTEST::Get(int i) { return((AAA*)GetAt(i)); } void CTEST::Erase(void) { int i; AAA *p; for (i = 0; i < GetSize(); i++) { p = (AAA*)GetAt(i); delete p; p = NULL; } RemoveAll(); } CTEST::Sort(Comp, 0, GetUpperBound()) { // 再帰ソート(省略) } AAAというのは自身で用意したクラスで情報群メンバに持ち、メンバ関数で個々の情報を取り出すクラスです。 自分ではソート処理でアドレスを壊してるのかなぁと推測してEraseでダンプしてみたんですが、別におかしくない様に思えました。 最後まで実行されずにというのはEraseで確保した領域を開放していく過程で混合モードに入りメッセージボックスでブレイクポイントの設定位置 アドレスと表示されるということです。一旦勝手にブレイクするのは何故?というのが私の知りたい事です。ちなみにF5で再実行すると何も無かったように正常に終了します。 以上補足したつもりですが、お願いします。 >基本的にはデバッグ情報が無い場合 特に設定をいじらずプロジェクトを作ったつもりですが、デバッグ情報が無いというのはどういう事ですか?聞いてばっかりですみません。

関連するQ&A

  • C++ リストの末尾要素の削除

    連結リストの末尾の要素を削除するプログラムを教えてください。 自分で何度も書き直してみたのですが、どうしてもうまくうごきません。 自分で書いた現状が以下のものですが、止まってしまいます。 void List::removeLast(){ if (head == NULL)return; Cell *p = head; Cell *prev = NULL; while (p!= NULL){ prev = p; p = p->next; } delete prev; } 以下のプログラムが動かすにはremoveLast()をどう変えたらよいのでしょうか? よろしくお願いします。 #include <iostream> using namespace std; // クラスの宣言 class Cell { friend class List; // Listクラスから,このクラスに自由にアクセスできるようにする private: int data; // データ Cell *next; // 次のセルのアドレスを指すポインタ public: Cell(int _data, Cell *n = NULL){ data = _data; next = n; } }; class List { private: Cell *head; // 連結リストの先頭要素のアドレスを指すポインタ public: List(){ head = NULL; }; ~List(){ while (head != NULL)removeFirst(); } void addFirst(int data){ head = new Cell(data, head); } void removeFirst(){ if (head == NULL)return; Cell *removed = head; head = head->next; delete removed; } void removeLast(); void print(){ for (Cell *p = head; p != NULL; p = p->next){ cout << p->data << ' '; } cout << endl; } }; // 連結リストの末尾要素を削除する関数 void List::removeLast() { //この部分です } int main() { List l1; for (int i = 0; i < 10; i++) { l1.addFirst(i); } l1.print(); l1.removeLast(); l1.print(); l1.removeLast(); l1.print(); l1.removeLast(); l1.print(); return 0; } 要求される実行結果は以下の通りです リストの内容: 9 8 7 6 5 4 3 2 1 0 リストの内容: 9 8 7 6 5 4 3 2 1 リストの内容: 9 8 7 6 5 4 3 2 リストの内容: 9 8 7 6 5 4 3

  • OLEObjects ステップイン 削除できない

    シート上のOLEObjectsを削除するべく、 ActiveSheet.OLEObjects.Delete と言うコードをステップインで実行しようとすると、 「中断モードでは入力できません」 となりますが、OLEObjectsは削除されます。 結局は削除されるからいいのですが、 ステップインで実行していきたい時は、どうすればいいのでしょうか? そもそもなぜデバッグモードで、OLEObjectsの削除ができないのでしょうか? エクセル側に何か不都合があるのですか?

  • C++ 連結リストの要素の削除について

    リストで任意の場所の要素を削除するプログラムを考えているのですが、どうしてもその部分のプログラムにmain関数通りの動きをさせる方法が分かりませんでした。いろいろ試してみたのですが、どこかしらでおかしくなってしまうのです。 以下に私がつくった途中までのプログラムを示すので、removeAt(int index)の中身の例を教えて頂きたいのです。よろしくお願い致します。 #include <iostream> using namespace std; // クラスの宣言 class Cell { friend class List; // Listクラスから,このクラスに自由にアクセスできるようにする private: int data; // データ Cell *next; // 次のセルのアドレスを指すポインタ public: Cell(int _data, Cell *n = NULL){ data = _data; next = n; } }; class List { private: Cell *head; // 連結リストの先頭要素のアドレスを指すポインタ public: List(){ head = NULL; }; ~List(){ while (head != NULL)removeFirst(); } void addFirst(int data){ head = new Cell(data, head); } void removeFirst(){ if (head == NULL)return; Cell *removed = head; head = head->next; delete removed; } void removeAt(int index); void print(){ for (Cell *p = head; p != NULL; p = p->next){ cout << p->data << ' '; } cout << endl; } }; // 連結リストの index 番目の要素を削除する関数 void List::removeAt(int index) { //この部分です } int main() { List l1; for (int i = 0; i < 10; i++) { l1.addFirst(i); } l1.print(); l1.removeAt(0); // リストの先頭要素で動作確認 l1.print(); l1.removeAt(2); l1.print(); l1.removeAt(4); l1.print(); l1.removeAt(17); // リストの要素数より大きな引数で動作確認 l1.print(); l1.removeAt(0); // リストの先頭要素で動作確認 l1.print(); l1.removeAt(6); // リストの要素数より大きな引数で動作確認 l1.print(); l1.removeAt(5); l1.print(); return 0; } 要求される実行結果は以下の通りです リストの内容: 9 8 7 6 5 4 3 2 1 0 リストの内容: 8 7 6 5 4 3 2 1 0 リストの内容: 8 7 5 4 3 2 1 0 リストの内容: 8 7 5 4 2 1 0 リストの内容: 8 7 5 4 2 1 0 リストの内容: 7 5 4 2 1 0 リストの内容: 7 5 4 2 1 0 リストの内容: 7 5 4 2 1

  • 多次元配列のメモリ解放

    多次元配列のメモリ解放についてです。 以下のような方法で多次元配列を確保した場合に、 --- char** ppMain; ppMain = new char*[3]; for (int i = 0; i < 3; i++){ ppMain[i] = new char[20]; } --- メモリ解放する場合、 --- for (int i = 0; i < 3; i++){ delete [] ppMain[i]; ppMain[i] = NULL; } delete [] ppMain; ppMain = NULL; --- で良いでしょうか? おそらく、new/deleteの回数が同じであれば問題ないと思うのですが。 少し混乱してしまって、 delete [] ppMain[i]; によって new char*[3]で確保したところも解放されており delete [] ppMain; が必要なく危険な領域まで解放しようとしているということはないでしょうか? ご専門、お詳しいかたコメント宜しくお願いします。

  • case で宣言コンパイルエラー

     switch (msg){  case WM_LBUTTONDOWN:   char *p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; がエラーで  switch (msg){  case WM_LBUTTONDOWN:   char *p;   p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; と  switch (msg){  case WM_KEYDOWN:   if( wParam == VK_RETURN ){    char *p = new char[1000];    wsprintf(p, "%d" , i);    MessageBox(hWnd , p , "" , MB_OK);    delete[] p;   }  break; ならエラーじゃなかったんだけど、理由がよく分かりません。 case のすぐ下で宣言と同時に値を代入してはいけないんですか?

  • 意味がわかりません

    この部分の意味がわからなくて困っています。わかる方いましたら解説をお願いします。m(_ _)m public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; if(f==0){ bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=0;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 1; } else if(f==1) { bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=1;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 0; } }

    • ベストアンサー
    • Java
  • Oracle9iデータベースの削除について

    SQL*Plusを使ってOracli9iのレコードをdeleteしたのですが、commitを忘れたままパソコンから離れ、パソコンの前に戻ったときにSQL*Plusがデータベースから切断されていたので、もう一度接続して同じレコードのdeleteを実行したのですが、SQL*Plusがフリーズしてしまって削除することが出来なくなっていました。commitしても正常にデータベースにそのレコードの削除が反映されません。どうすればそのレコードを削除出来るようになるのでしょうか?

  • 双方向リストのプログラミングのチェック

    指定したファイルを読み込み、一行ずつ構造体に保存し、表示させる。その後、キーボードから指定した行を削除し、処理後の結果を表示させる・・・といったプログラミングを作成しています。 通常の表示の部分はできましたが、後は指定した行の削除の部分ができません。 あらかじめHPで調べてあるので、削除するときは、その削除したい行をまたいで、前後のリストを繋げるといった概念的なのは大体理解できました。 自分なりに考えたり調べて、下のように打ちました。 ですが、キーボードから入力した値をどう関数に対応させていくのか、 delete_head,delete_tailの関数の部分に出る、head,tailは使えない的なエラーの対処の仕方がわからなく、詰まってます。 アドバイス、他にも直す場所等ありましたらお願いします。 #include<stdio.h> #include<stdlib.h> #define LINE 1000 typedef struct num{ char line[LINE]; struct num *next; struct num *prev; }Num; void normal(Num **,Num **,char *); void reverse(Num *,Num *,char *); void delete_head(void); void delete_tail(void); void delete(Num *target); int main(int argc,char *argv[]) { FILE *fp; char line[LINE]; int i=0,j; Num *head,*tail,*p; head=NULL; tail=NULL; fp=fopen("test.txt","r"); if(fp==NULL){ fprintf(stdout,"File not found.\n"); exit(1); } while(fgets(line,LINE,fp)!=NULL) { normal(&head,&tail,line); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); p=tail; while(p!=head){ printf("%s\n",p->line); p=p->prev; } printf("%s\n",p->line); printf("input number\n"); scanf("%d",&j); p=head; for(i=0;i<=j;i++);{ p=p->next; } if(p==head){ delete_head(void); } else if(p==tail){ delete_tail(void); } else{ delete(p->prev); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); fclose(fp); return 0; } void normal(Num **s,Num **e,char *g){ Num *tmp; int i; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*e)=(*s); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ (*s)->line[i]=g[i];} (*s)->next=*e; (*s)->prev=*s; } else{ tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=(*e); (*e)->next=tmp; tmp->next=(*e); (*e)=tmp; } return ; } void reverse(Num *kan1,Num *kan2,char *g){ Num *tmp; int i; tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=kan1; kan1->next=tmp; tmp->next=kan2; kan2->prev=tmp; return ; } void delete_head(void){ Num *second=head->next; if(secound==NULL){ free(head); head=NULL; tail=NULL; } else{ second->prev=NULL; free(head); head=second; } } void delete_tail(void){ Num *second_last=head->prev; if(second_last==NULL){ free(tail); head=NULL; tail=NULL; } else{ second_last->next=NULL; free(tail); tail=second_last; } } void delete(Num *target){ Num *after_target; Num *before_target; after_target=target->next; before_target=target->prev; after_target->prev=target->prev; before_target->next=target->next; free(target); }

  • 配列について、その要素を並べ替えて得られる配列を重複することなく全て得たいです。

    要素数が5つなら5!で120通り、nであればn!通りの配列をすべて得たい、といった具合です。 自分で組んでみたところ、再帰呼び出しを多用しているせいか要素を8つにした時点でFirefoxだと「このページのスクリプトは処理に時間がかかっているか応答しなくなっています。…」、IEでも似たような警告文が表示されてしまいます。 コードは以下に示すとおりです。 そこでお聞きしたいのは、  1.「処理に時間が~云々」などの表示をさせずに処理を   続けさせるにはどのように書いたらいいか  2.もっと短くスマートなコードで全走査できないか の2つです。 1.についてはユーザサイドでなく開発者サイドで、かつalertを使う以外の方法で、警告文を出させないで処理を続けさせるためにはコードをどのようにしたらよいでしょうか。 2.に関しては、私が書いたコードは正直わかりにくいと思いますので、もっとシンプルに全走査できるアルゴリズムがあったら教えてほしいです。 どうかよろしくお願いします。 <html> <body> <script type="text/javascript"> <!-- //Arrayオブジェクトに自身をコピーした配列を返すclone()メソッド追加 Array.prototype.clone = function(){ // 自分自身が配列かをチェック if(this[0].constructor == Array ){ var ar, n; //新しい配列を用意する ar = new Array(this.length); for(var n=0;n<ar.length;n++){ //再起呼び出しで配列の中身をコピー ar[n] = this[n].clone(); } //作成した配列を返す return ar; } return Array.apply(null,this); } //★要素を並べ替える前の配列の宣言 var ar = new Array("1","2","3","4","5","6","7","8"); //並べ替え後の配列を格納する配列宣言 var arranged_ar = new Array(); function arArrange(){ //引数は(呼び出した節の、並び替える前の配列内での順番,すでに取り出した節の配列,兄弟の配列) function createBranch(parentCounter,parentNodes,sameDepthBranches){ var branches = new Array(); //呼び出した節の子ノード格納用の配列宣言 branches = sameDepthBranches.clone(); //呼び出した節の兄弟をコピー branches.splice(parentCounter,1) //呼び出した節を除いて子ノードの配列作成完了 var pushed_ar = new Array(); //この節以前に登場した節を格納する(最終的に並べ替え終わった配列になる)配列宣言 pushed_ar = parentNodes.clone(); //呼び出し元のpushed_arをコピー for(var i=0;i<branches.length;i++){ pushed_ar.push(branches[i]); //pushed_arに子ノードを1つ追加 //走査が葉ノードに達したときの処理 if(pushed_ar.length == ar.length){ var length = arranged_ar.length; arranged_ar[length] = new Array(); for(var j=0;j<pushed_ar.length;j++){ arranged_ar[length].push(pushed_ar[j]); //arranged_arに並び替え後の配列を格納 } //走査がまだ葉ノードに達していない場合の処理 }else{ createBranch(i,pushed_ar,branches); //自身を再帰呼び出しすることで葉ノードに達するまでループ } //子ノード以下の走査が終わった場合の処理 pushed_ar.splice(pushed_ar.length-1,1); //追加した子ノードを削除して次の子ノード追加へ } return; } //↑で宣言したcreateBranch関数の呼び出し for(i=0;i<ar.length;i++){ var tempAr = new Array(); tempAr.push(ar[i]); createBranch(i,tempAr,ar); } //結果をresultに格納 var result = ""; for(var i=0;i<arranged_ar.length;i++){ result += i+1 + ": "; for(var j=0;j<arranged_ar[i].length;j++){ result += arranged_ar[i][j] + ","; } result += "<br>"; } //結果を画面に表示 document.getElementById("result").innerHTML = result; return; } --> </script> <input type="button" value="全並べ替えパターン走査" onclick="arArrange();"> <p id="result">ここに結果表示</p> </body> </html>

  • 双方向リストのバブルソートについて

    双方向リストをバブルソートを用いてソートしたいです。 下記がプログラム(一部)ですが、ソートした後にリスト表示すると 無限ループに陥ります。 どこがいけないのでしょうか。 #include <stdio.h> #include <stdlib.h> struct cell{ int data; struct cell *next, *prev; }; void insert_head(struct cell **head, int num){ struct cell *p, *p1; p = *head; p1 = make_cell(); *head = p1; p1->data = num; p1->next = p; if(p1->next != (struct cell *)NULL){ p1->next = p; p->prev = p1; } } void print_list(struct cell *head){ struct cell *p; p = head; printf("data = \n"); while(p != (struct cell *)NULL){ printf("%d\n", p->data); p = p->next; } } void sort_list(struct cell **head){ struct cell *p, *p2; int i, n; n = 0; p = *head; while(p->next != (struct cell *)NULL){ p = p->next; n++; } for(i = 0, p = *head; i < n-2; i++){ if(p->data > p->next->data){ if(p == *head){ *head = p->next; }else{ p->prev->next = p->next; } p2 = p->next; p->next = p->next->next; p->next->next = p; p->next->next->prev = p; p->next->prev = p->prev; p->prev = p2; }else p = p->next; } } int main(void){ struct cell *head = (struct cell *)NULL; int n; while(1){ printf("1:Insert head 2:Insert tail 3:Delete 4:List 5:Sort 6:Exit\n"); scanf("%d", &n); switch(n){ case 1: printf("num = "); scanf("%d", &n); insert_head(&head, n); break; case 2: printf("num = "); scanf("%d", &n); insert_tail(&head, n); break; case 3: printf("num = "); scanf("%d", &n); delete_cell(&head, n); break; case 4: print_list(head); break; case 5: sort_list(&head); break; case 6: return 0; break; } } }

専門家に質問してみよう