
char *p = new char[SIZE];
上記の方法で動的メモリを確保した場合
確保したメモリの初期化は、
memset(p, 0x00, SIZE);
のほかに方法はありますでしょうか?
個人的にSIZEを指定してしまうのがキレイではないような気がしています。
memset(p, 0x00, sizeof(p));
では、sizeof(p)はchar* のサイズなので正しく初期化できず、
for (int i = 0; i < SIZE; i++){
memset(p[i], 0x00, sizeof(p[i]));
}
では、コンパイルエラーが出てしまいます。
(new char[SIZE]で確保した場合には、p[i]のように配列としてアクセスできないのでしょうか?
単にchar p[SIZE]の場合には、当然配列としてアクセスできるのに。。。)
一般的な初期化方法のほかにも何かコメントでも良いので経験あるかたいらっしゃいましたら教えてください。
宜しくお願いいたします。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.7
- 回答日時:
char *p = new char[SIZE];
で確保した領域を
memset( p, 0, 何らかのサイズ );
としても危険はありません。
処理系にも依存しません。
これは配列の要素が汎整数型だからです。
非POD型の場合は危険ですし、POD型の場合でも、ポインタ型や浮動小数点型、またはそれらを含む集成体の場合も安全とはいえません。
型によって、安全であったり、そうでなかったりするので、よく分からないならmemsetは使わない方が無難です。
最低限std::fill_nを使うようにしましょう。
なお、もっとも安全なのは、そもそもnewを使うのはやめてstd::vectorにすることです。std::vectorを使えば、SIZEを持ちまわってどうこうという問題もなくなります。
>memset( p, 0, 何らかのサイズ );
>としても危険はありません。
"何らかのサイズ"がSIZE以上の場合には
危険ではないでしょうか?
>std::vectorを使えば、SIZEを持ちまわってどうこうという問題もなくなります。
vectorの場合は生成と同時に初期化されるということですね。
No.6
- 回答日時:
リクツを言えば、
char *p = new char[SIZE];
で確保した領域を
memset( p, 0, 何らかのサイズ );
とするのは、こわいです。
処理系が変われば、どのような結果になるかわかりません。
率直に
for( i = 0; i < SIZE; i++ ) p[ i ] = 0;
なら、間違いありません。
>memset( p, 0, 何らかのサイズ );
>とするのは、こわいです。
確かにご指摘のとおり、
"何らかのサイズ"によっては
簡単にオーバーフローしますね。
ご指摘ありがとうございます。
No.5
- 回答日時:
> 個人的にSIZEを指定してしまうのが
> キレイではないような気がしています。
なぜですか?
確保したSIZE分クリアしなければならないのだから、
SIZEを渡すことはむしろ当然のことと思いますが?
>memset(p[i], 0x00, sizeof(p[i]));
既に出ていますが、p[i]はポインタ型では有りません。
上記はchar1個に対してmemsetを呼び出す大変無駄なコードです。
こんなことをするくらいなら p[i] = 0;の方が遥かにましでしょう。
まずは、char p[SIZE];で宣言されたpと
char* p;で宣言されたpの違いを理解してください。
前者の型は char[SIZE]型のpで、後者はchar*型のpです。
故に前者でのsizeof(p)はchar[SIZE]分のサイズなのに対し
後者のpではchar*分のサイズとなります。
C言語上では配列の先頭は暗黙の変換によりchar*となりますが、
関数呼び出しなどで渡された物を除き、宣言されたスコープの中では
宣言された型を保持します。
今回はC++なのかnewが使われていますが、
C言語であれば、確保した領域の0クリアが保障されている
callocなどもあります。
>SIZEを渡すことはむしろ当然のことと思いますが?
初心者ながらsizeof(...)で指定できたほうがコード修正が楽になる場合もあると思い、何か方法があれば。。。という気持ちで質問させていただきました。
>前者の型は char[SIZE]型のpで、後者はchar*型のpです。
>故に前者でのsizeof(p)はchar[SIZE]分のサイズなのに対し
>後者のpではchar*分のサイズとなります。
理解していたはずなのですが、この説明はすごくわかりやすいです!
char[SIZE]型であると理解できれば当然のことですね。
根本的な考え方が間違っていたんですね。
ご指摘、有難うございます。
No.4
- 回答日時:
> for (int i = 0; i < SIZE; i++){
> memset(p[i], 0x00, sizeof(p[i]));
> }
> では、コンパイルエラーが出てしまいます。
p[i]がポインタではないので第一引数でargument mismatchを起してるだけでしょう。
&p[i]でないと。
No.3
- 回答日時:
pがchar*型である限り、それが指している領域のサイズは
コンパイラにはわからないので、初期化時にSIZEを再指定する
しかないでしょう。
stdライブラリが使えないのであれば、
次のようにchar[SIZE]をクラス化してしまう
手もあると思います。
class char_array{
public:
char_array() {memset(c,0,sizeof(c));}
char c[SIZE];
};
char_array *p = new char_array();
No.2
- 回答日時:
newを使って配列を直接割付けなければならない理由があるのでしょうか?
特別な理由がなければstd::vectorを使う方が得策です。
コンパイラが古いとか、Embedded C++だとか、フリースタンディング環境だとか、その他諸々の組込み向けの方言だとかであれば仕方ないでしょうが...
vector<char> p(SIZE);ですね。
初心者なので教えてほしいのですが、1つの文字列のための領域を確保するときにでも普通はあまりnewは利用しないのでしょうか?
明示的にdelete操作できるのがnewの良さかなと思っていたのですがそういったことは経験上なかったでしょうか?(回答を拝見するとなさそうですが。。。)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- 英語 量を"size"で表現することの可否等について 1 2022/12/07 14:49
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringからchar*への型変換に...
-
C言語のintとcharの違いってな...
-
char*を初期化したいのですが
-
char *str; と char* str;
-
C# ポインタ アクセス違反
-
C++17で、unsigned char * 配列...
-
【初心者】C言語の関数の仕様に...
-
VC++6.0にて、文字列処理にて困...
-
C言語にて構造体のメンバがNULL...
-
文字型配列に格納した空白の切捨て
-
fstream型オブジェクトを関数の...
-
ASCIIコードへの変換方法
-
動的メモリの初期化方法について。
-
入力された文字列の中の数字を...
-
ostringstreamではまりました
-
csvファイルをfscanfで読み込む...
-
char 文字列型 の表現範囲が-12...
-
多次元配列のメモリ解放
-
wsprintf( ポインタ , "%d" , "...
-
しつこい様ですが、再度ポイン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
C言語のintとcharの違いってな...
-
DWORDとcharの変換
-
C++17で、unsigned char * 配列...
-
char 文字列型 の表現範囲が-12...
-
new charとnew char[N]の違いは?
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
小数点入りの文字列をfloat型に...
-
文字型配列に格納した空白の切捨て
-
fstream型オブジェクトを関数の...
-
C++Builder 2009 テキスト...
-
文字列の途中から途中までを抽出
-
C言語の文字リテラル中の16進文...
-
エクセルのMID関数は、C言語では?
-
文字列のswap
-
void型へのポインタ
-
VC++ char[10]へのCString値の代入
おすすめ情報