忙しい現代人の腰&肩のお悩み対策!

こんにちは。

C++では、プログラムの終了時に、全てのクラスオブジェクトは、デストラクタが呼び出されて破棄されますが、プログラムの途中で、クラスオブジェクトを明示的に破棄する方法はあるのでしょうか?

例えば、new演算子によってメモリを動的に割り当てたポインタなら、delete演算子で破棄できますが、
クラスオブジェクトにdelete演算子は使えないようです。

何かいい方法を知っておられる方がいらっしゃれば、是非アドバイスを頂きたいと思います。

このQ&Aに関連する最新のQ&A

A 回答 (8件)

ClassA *p = new(buf) ClassA;



ClassA *p = new ClassA;
の意味は違います. 後者はメモリを割り当てますが, 前者ではメモリの割り当ては行われません. placement new なんかで調べてもらうといいかな.
    • good
    • 1
この回答へのお礼

御回答ありがとうございます。

placement newは、new演算子関数に、引数を与える機能のようですね。
はじめて知りました。
今回の場合、bufの指すアドレスを、pが指すようにしているのだと分かりました。
(printf("%p", buf); と pring("%p", p); で表示されるアドレス値が同じでした。)

お礼日時:2011/09/17 06:46

ちょっと気になるんですが明示的に破棄したいコードがあるんですか?


それとも単なる興味?
いや興味ならいいんですが、ただ素直にnew-deleteすればいいのになぁと思ったので。

>No1の型の回答に書いた通り、「クラスオブジェクト」とは、何らかのクラス型のオブジェクトの事です。
>普通はどのように呼ぶべきなのでしょうか?
自動変数のクラス?
私なら簡単なソースを書いて「このローカル変数nを明示的に破棄したい」という風な書き方にしますかね。

>普通は単に「オブジェクト」というのかもしれませんが、普通の変数など、他のオブジェクトとの区別をするために、その様に読んでいます。
str_type *p = new str_type; //←newしたデータ=オブジェクト(=インスタンス)
何か勘違いしてるみたいですけど、オブジェクトって物凄く広い意味で使われるので曖昧回避したい場合は極力使わない方がよい単語です。
ちなみにNo.1氏の「class_a」や上に書いた「*p」なんかをインスタンスと呼びます。
インスタンスもオブジェクトの一種です。(厳密に言うと違うものらしいですが)
    • good
    • 1
この回答へのお礼

御回答ありがとうございます。

>ちょっと気になるんですが明示的に破棄したいコードがあるんですか?
いや、そういうわけではありません。

>何か勘違いしてるみたいですけど、オブジェクトって物凄く広い意味で使われるので曖昧回避したい場合は極力使わない方がよい単語です。
ちなみにNo.1氏の「class_a」や上に書いた「*p」なんかをインスタンスと呼びます。

御指摘ありがとうございます。
http://itpro.nikkeibp.co.jp/free/NIP/NIPCOLUMN/2 …
にオブジェクトとインスタンスについて、分かりやすく説明されていました。
間違いに気がついて良かったです。

お礼日時:2011/09/17 06:35

すでに #5 の方が回答されていますが、デストラクタはオブジェクトを破棄するためにあるのではなく、オブジェクトが破棄されるときに後処理をするためにあります。

デストラクタ自体は、他のメンバ関数(メソッド)と同様に1メンバ関数に過ぎませんが、C++ の仕組みとして、オブジェクトが破棄されるときにデストラクタがあれば自動的にコールするようになっている、という仕組みになっています。デストラクタをプログラム中から意図的にコールするというのは、あまりやらないですね・・・・・・・。

いろいろ試してまた疑問が出てきて解決していけば、そうやっていくうちにいろんな間違って覚えていたことが修正されていくのは技術向上の鉄則です。頑張ってください^^。
    • good
    • 0
この回答へのお礼

御丁寧にありがとうございます。
頑張ります。

お礼日時:2011/09/16 16:04

> プログラムの終了時に、全てのクラスオブジェクトは、


> デストラクタが呼び出されて破棄されますが
逆ですね。
「オブジェクトが破棄される時にデストラクタが呼び出される。」
だと思います。

なので、追加質問でも
> ob.str_type::~str_type();
では、単にデストラクタを明示的に呼び出しただけでobは破棄されず
スコープから外れた時に破棄されてもう一度デストラクタが呼ばれた
のだと思います。
    • good
    • 0
この回答へのお礼

御回答ありがとうございます。

なるほど、僕が勘違いしていたみたいですね。
という事は、デストラクタを呼び出しただけでは、
オブジェクトは破棄されないのですね。
よーく分かりました。

お礼日時:2011/09/16 10:32

多分、そんなことはないと思いますが…


もしかして、クラスオブジェクトって、クラスメンバー(クラスの静的メンバー, クラスのstatic変数)のことを指しているわけではないんですよね?
    • good
    • 0
この回答へのお礼

御回答ありがとうございます。
分かりにくくて申し訳ございません。
No1の型の回答に書いた通り、「クラスオブジェクト」とは、何らかのクラス型のオブジェクトの事です。
普通はどのように呼ぶべきなのでしょうか?

お礼日時:2011/09/16 00:03

無理すれば



char buf[sizeof (ClassA)];
ClassA *p = new(buf) ClassA;
// なんかする
p->ClassA::~ClassA();

ともできるけど普通はスコープで対応する... あぁそうか, 「プログラムの終了時に、全てのクラスオブジェクトは、デストラクタが呼び出されて破棄されますが」という認識がおかしいんだ.

この回答への補足

Tacosanさん、
ClassA *p = new(buf) ClassA;
は、pにサイズbufのメモリを動的に割り当て、
ClassA型オブジェクトの先頭を指すようにするという意味でよろしいのでしょうか?
だとすると、単に
ClassA *p = new ClassA;
だけでも良いと思うのですが、如何でしょうか?

あと、
ClassA *p = new(buf) ClassA;
で、オブジェクトポインタにメモリを割り当てた後、
そのまま終了しても、ClassAクラスのデストラクタは呼び出されませんでした。
オブジェクト変数を生成しない限り、デストラクタは呼び出されないのでしょうか?



オブジェクトポインタ

補足日時:2011/09/16 03:36
    • good
    • 0
この回答へのお礼

Tacosanさん、いつも御回答、ありがとうございます。

p->ClassA::~ClassA();
のように、デストラクタを明示的に呼び出せる事は知りませんでした。

あまり大きなプログラムを作成した事がないので、
「普通はスコープで対応する」という事は、考えた事がありませんでした。
これからは、そういった認識を持つようにします。

お礼日時:2011/09/16 00:08

#1 の方の回答で、やりたいことができるのでは、と思うのですが、オブジェクトのライフタイムの認識があってないかもしれません・・・・・・。



オブジェクトのライフタイムは記憶クラスの「スコープ内」です。スコープが終了するときには破棄されます。関数やメソッド、{}で囲まれたブロック内で宣言しているオブジェクト変数(auto 記憶クラス)であればそれらが終了する時です。もちろん static などで確保されているクラス変数は、プログラムが終わるまで破棄されません。

この回答への補足

追加質問です。
str_typeというクラスを定義し、main関数で
str_type ob;
ob.str_type::~str_type();
のようにすると、コンストラクタとデストラクタが呼び出されたのですが、
プログラムの終了時に、デストラクタがもう一度呼び出されました。
ob.str_type::~str_type();
によって、obは破棄されたはずなのに、なぜこういった事が起こるのでしょうか?

補足日時:2011/09/16 03:42
    • good
    • 0
この回答へのお礼

御回答ありがとうございます。

今まで、オブジェクトのライフタイムについては、深く考えた事がありませんでした。
特に、「記憶クラスのスコープ」というものの認識があいまいなようです。
勉強し直してきます。

お礼日時:2011/09/16 00:13

……クラスオブジェクト?なんのこっちゃ?



とりあえずやりたいことはこれかな?

class ClassA
{
};

int main(int argc, char** argv)
{
 ClassA class_a;
 // 何らかの処理-1
 delete class_a; // もちろん間違いだけどこれと似たようなことがやりたい
 // 何らかの処理-2
 return 0;
}

もし上のようなことがしたいならば、変数のスコープを利用して以下のようにすれば可能です。

int main(int argc, char** argv)
{
 {
  ClassA class_a;
  // 何らかの処理-1
  // オブジェクト破棄のための文は書く必要がない
 }

 // 何らかの処理-2
 return 0;
}

この回答への補足

試させていただきた所、 } のところできちんと破棄されました。
ありがとうございました。

補足日時:2011/09/16 00:02
    • good
    • 0
この回答へのお礼

御回答ありがとうございます。

僕が言っている「クラスオブジェクト」は、記述して下さったプログラムのclass_aの事です。
普通は単に「オブジェクト」というのかもしれませんが、普通の変数など、他のオブジェクトとの区別をするために、その様に読んでいます。
僕がやりたかった事は、当に最初に記述していたプログラムのような事です。
2つ目のプログラムでは、main関数の中で、{ }で括った部分のオブジェクトは、処理が } まで進むと自動的に破棄されるというものですよね。
そのような事ができるとは知りませんでした。
試させていただきます。

お礼日時:2011/09/15 23:59

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QC++ 構造体の一括初期化 {0}

構造体変数に {0} を代入すると、CString は空文字、 intは0に一括で初期化されるようです。
なんでこんなことが出来るのでしょう?
{0}は何?
仕組みを教えて下さい!!

Aベストアンサー

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用体の場合、最初の名前つきメンバにa)~d)の規定を
>(再帰的に)適用し初期化する。

なので、zero初期化されていることが、規格で保証されます。

typedef struct hoge_struct
{
 int a;
 int b;
} hoge_struct;

static hoge_struct initializer; //初期化用変数。値は変えない。

int main(void)
{
 hoge_struct hoge;
 hoge = initializer;
 return 0;
}
真っ白に何度も初期化したいなら、こんな感じでどうでしょう?
関数を用意して初期化すると、構造体のメンバが増えると関数も修正しないといけない
ですが、これだと関数を変更しなくてすむし。

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用...続きを読む

QC++のnewで確保したメモリーの解放の確認方法

C++で作成中のプログラムの一部で、長い文章も処理できるように、構造体とメモリーの動的確保を使用しています。
ただ、動的に確保したメモリーは自分で解放しなくてはならないのですが、プログラムが単純なうちは開放のミスを発見できますが、長くなるとバグで一部開放されない可能性も捨てきれません。

そのようなときに全て開放できたか確認する方法は無いのでしょうか?

開発環境につきましては、
OS WindowsXP HomeEdition
コンパイラ BCC
言語 C++ コンソールアプリケーション

struct string {
char str[512];
struct string* nextstr;};
簡単には、このような構造体を new で確保し、開放は、先頭から delete してますが、
構造体がこれより結構複雑なため、処理部が長くきちんと開放できているか自信が有りません。

Aベストアンサー

newやdeleteをdefineで括ってまとめて監視してはどうですか?

extern int g_count;
#define NEWOBJECT(T) new (T); g_count++
#define DELETEOBJECT(ptr) delete (ptr) ; g_count--
int g_count;
//ここのstringは自分で定義した構造体
string *p = NEWOBJECT(string);
DELETEOBJECT(p);
printf("メモリ確保数=%d",g_count);

のようにするとか、
リリース版の時は
#define NEWOBJECT(T) new (T)
#define DELETEOBJECT(ptr) delete (ptr)
とすれば余計の処理も消えますし。

Qc++,ある関数のクラスから別のクラスの関数を呼ぶ

c++で、あるクラスのメンバ関数から、別のクラスのメンバ関すを呼びたいのですが、どのようにしたらできますか?
例えば、以下のような単純なコードを考えています。やりたいことは、Aのメンバ関数であるaaa()からBのクラスであるbbb()を呼びたいと思っています。その理由を少し説明します。ここでは、Aというクラスとmain関数はオープンソースコードを例えています。できるだけ、元のオープンソースコードを書き換えずに新たな機能を拡張したいと思っています。そこで、Bというクラスを使って、元のオープンソースコードに機能を拡張しようとしています。このような理由なので、bbb()という関数はaaa()という関数から呼びたいです。メイン関数には何も書き加えないのがベストです。
現状では、実行すると「this is aaa」という出力しか出ません。ここに「this is bbb」の出力を加えたいです。クラスAとBにある程度コマンドを追加して、解決できないでしょうか。

#include <iostream>
using namespace std;

//------------------------------------------------------
class A{
public:
void aaa();
virtual void bbb(){}
};
//------------------------------------------------------

//------------------------------------------------------
class B : public A{
public:
void bbb();
};
//------------------------------------------------------

//------------------------------------------------------
void A::aaa()
{
cout << "this is aaa \n";
bbb();
}
//------------------------------------------------------

//------------------------------------------------------
void B::bbb()
{
cout << "this is bbb \n";
}
//------------------------------------------------------

//------------------------------------------------------
int main()
{
A a;
a.aaa();
return 0;
}
//------------------------------------------------------

c++で、あるクラスのメンバ関数から、別のクラスのメンバ関すを呼びたいのですが、どのようにしたらできますか?
例えば、以下のような単純なコードを考えています。やりたいことは、Aのメンバ関数であるaaa()からBのクラスであるbbb()を呼びたいと思っています。その理由を少し説明します。ここでは、Aというクラスとmain関数はオープンソースコードを例えています。できるだけ、元のオープンソースコードを書き換えずに新たな機能を拡張したいと思っています。そこで、Bというクラスを使って、元のオープンソー...続きを読む

Aベストアンサー

Aを極力触りたくないのであれば、あまりカッコよくありませんが、AがBを継承するではどうでしょうか?
提示コードを以下のように書き換えれば、とりあえず期待する動きはすると思います。

//------------------------------------------------------
class B {
public:
virtualvoid bbb();
};
//------------------------------------------------------

//------------------------------------------------------
class A: public B{
public:
void aaa();
};
//------------------------------------------------------
※ その他はそのまま

QCStringからchar*への型変換について教えてください。

以前の質問に

int型 → CString型/char型

がありましたが、

CString型をchar*型に変換する方法を
教えていただければありがたいです。

MSDNで「LPCTSTRキャスト」が説明されていましたが、
例が載ってないのでよくわかりませんでした。

よろしくお願いします。

Aベストアンサー

目的にもよりますが一時的にchar配列として使いたいならCString::GetBuffer()が利用できます。
char配列としての利用が終わったらCString::ReleaseBuffer()する必要がありますが。

直接CString内の文字列を扱う必要があるならCString::operator LPCTSTRで文字列ポインタが得られます。
ただし、CStringオブジェクトをいじると無効ポインタなる可能性があるので気をつけてください。

MSDNのMicrosoft Foundation Classリファレンス→CString→クラスメンバで確認してください。

QGetPrivateProfileStringでiniファイル読込む処理を詳しく知りたいのですが・・・

お世話になっています。

iniファイルを読込み、各変数に代入するC言語のDLLを作成したいのです。
このサイトの投稿や、MSDNなどにも載っていたのですが、
少し理解に苦しみます。

現在まで、理解した点がwindows.hのインクルードを
記述するところ辺りです。
iniファイルは下記のようなレイアウトです。

---<mst.ini>----------------------------
[user]
name=username
ID=userid
[pc]
pcname=FMV
----------------------------------------

#include<windows.h>は記述することまでは
分かりましたが、以下から進みません。。。

GetPrivateProfileString("")

初心者で申し訳ありませんが、お助け願います。

Aベストアンサー

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
                sizeof(strBuf),   // 上記のエリアのサイズ
                "mst.ini" );     // iniファイル名

解説:
iniファイル名をフルパスで指定しないとWindowsのディレクトリにあるものと判断されます。
Win9xなら「c:\windows」、WinNT系なら「c:\WinNT」。

[user]セクションのnameキーがないときは、デフォルト値で指定した値が設定させます。

復帰値「dwLen」は実際に設定した値(文字列)の長さが返されます。

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
             ...続きを読む

QC# インスタンスの破棄

C#でインスタンスの破棄を明示的に行いたいのですが、
実際の開発現場では、どのように行っているのでしょうか?

自分で調べると「ガベージコレクタ」が暗黙的に行っているようですが明示的には行わないのが普通なのでしょうか?
もしくは、「Dispose」を使用して明示的に行うのが普通なのでしょうか?

実際に開発されている方からすると簡単な事かもしれませんが教えて頂けると助かります。

以上ですが、よろしくお願いいたします。

Aベストアンサー

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム系のオブジェクトや
データベースとのコネクションなどです。これは開発会社や
開発チーム、案件によって若干違っていて、徹底するところや
適当なところもあります。個人的には徹底したい派ですが。。。

ガベージコレクションが発生するとプログラムの実行動作が
遅くなり、また瞬間的に大きな負担がかかることがあります。
そのため全てをガベージコレクタに任せるのではなく、
明示的に開放できるもの、メモリを大量に消費するものは
その都度、適切に開放していくことで処理効率が良くなります。

プログラミング関連の調べ物で、サンプルソース等を見ることが
あるかと思います。この時サンプルで明示的に開放していたら、
それは明示的に開放したほうが良いもの、と思いましょう。
これだけでもステップアップになりますね。

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム...続きを読む

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Qdeleteで開放するとエラーになる原因がわからない

deleteでメモリ開放するとエラーになる原因がわからないです。

下記のようなプログラムを作ったのですが、deleteのところでエラーがでます。
エラー内容は
「Windows によって ****.exe でブレークポイントが発生しました。
ヒープが壊れていることが原因として考えられます。****.exe または読み込まれた DLL にバグがあります。
あるいは、****.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。
可能であれば、出力ウィンドウに詳細な診断情報が表示されます。」
とでます。

ソースは
wchar_t *aaa = L"ほげほげ";
wchar_t bbb[200];

wcscpy(bbb, aaa);

delete aaa;

wprintf(L"%s\n", bbb);

getchar();
です。

どこに原因があるのでしょうか?

[環境]
WindowsXP+VisualC++2008 UNICODE使用

deleteでメモリ開放するとエラーになる原因がわからないです。

下記のようなプログラムを作ったのですが、deleteのところでエラーがでます。
エラー内容は
「Windows によって ****.exe でブレークポイントが発生しました。
ヒープが壊れていることが原因として考えられます。****.exe または読み込まれた DLL にバグがあります。
あるいは、****.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。
可能であれば、出力ウィンドウに詳細な診断情報が表示さ...続きを読む

Aベストアンサー

メモリを動的に取ったした時は、決まったやり方で解放します。
メモリを確保するにはC++では「new」、C言語では「new」が一般的です。
「new」で取ったメモリは「delete」で解放する、「malloc」は「free」を使う、というのも決まりです。(「new」で取ったメモリを「free」で解放するとエラーになります。「malloc」も同じ)

サンプルのコードでは、「new」で取っていないメモリ領域に対して「delete」をかけてしまっているのがエラーの原因です。
コンパイルを通すだけなら「delete」の部分を削除すればよいかと思います。

「new」と「delete」はC++をやる限り理解しなければならない命令文です。ここの理解がいい加減だと、C++では地獄を見ます。
できれば「C++ new delete」で検索をかけて、詳細を調べることをお勧めします。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング