初めて投稿させていただきます。
現在PC:98 OS:MS-DOS 言語:MS-C7.0のhugeモデル という環境で
プログラミングを行っております。しかし、config.sys,autoexec.batを
工夫してもメモリ不足を補えず、変数と動的にすることにしました。
c言語のテキストを参考に

kansu()
{
char *p;
p=(char *)malloc(256*256*sizeof(char));
if(p=null) printf("メモリ確保に失敗");


free(p);
}

とすると
kansu終了直後に"メモリアロケーションエラー"がでます。
自分ではどこが悪いのわからず、ここでお聞きすることにしました。
上記の中の原因、もしくは原因と考えられることを教えてください。
よろしくおねがいします。

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

A 回答 (4件)

問題のソースコードでは、


if(p == null) printf("...");
なのか、それとも質問どおり、
if(p = null) printf("...");
なのか、どちらなんでしょう?

後者なら、bagyoさんの回答で決まりなんじゃ
ないでしょうか?ただ、if(p = null)と書いた
とき、まずp=nullの代入計算が行われ、その
結果のpの値がifの条件判断に使われます。
したがって、if(null)としたのと同一なわけで、
その後のprintfのメッセージは表示されない
と思います。

後者の場合でもう一つ気になるのは、MS-Cは
知らないですが、Linuxのfreeシステムコールでは、
free(null)とした場合、何の動作も行われません。
MS-Cでもそのようになっているとすると、
pにnullが代入されていることによる影響は
ないはずです。

前者の場合、pにはmallocが返した正しいアドレスが
入っています(malloc後にpに値を代入したり、単項
演算子を適用したりしていない限りですが)。
私の失敗の経験から言って、mallocやfreeで
エラーがでるときには、ヒープ破壊が原因で
あることが多いです。ヒープとは、mallocで動的に
割り当てられたメモリのことで、ヒープ破壊とは、
mallocで割り当てられたメモリを超えて書き込みを
行い(例えばこの例では、p[70000] = 1とかすることです)、
ヒープメモリ領域を破壊することです。

ですから、関数kansuの中で、p[65535]を超えて書き込みを
していないかをチェックしてみたらいいかもしれません。また、
他にもmallocを行っている場所があれば、そちらもチェックして
みてください。
    • good
    • 0

こんにちわ。


 
if(p=null)の部分は、比較しているので、代入演算子の=ではなく、==で比較しなければならないと思います。
現在の状態では、pにNULLが代入されているので、最後のfreeでメモリを開放するときに、0番地を指しているので、その結果でアロケーションエラーを起こしていると思います。

ただ、この場合ですと p=null というのは真になるはずなので、"メモリ確保に失敗"というエラーメッセージを吐いているのではないかと思うのですが、いかがでしょうか?
    • good
    • 0

私はTurboCユーザだったのでMSCの事は


よくわかりませんが、
char *p;
だとnearポインタになり、64kまでしか
取れなかったような気がします。
char far *p;
または
char huge *p;
としてfarポインタかhugeポインタを
使う必要があるかもしれません。
farmalloc()、farfree()なんて関数がありませんか?

違っていたら、ごめんなさい、、、m(_ _)m
    • good
    • 0

if (p=null) ... は if (p==null) の間違いではないですかね.



あと,・・の中はどういった処理をしているのでしょうか.
    • good
    • 0

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

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

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

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

Qfor(s=p; *p; p++)の*p(ポインタ)の意味

for(s=p; *p; p++)の*p(ポインタ)の意味
C言語初心者です。
今ポインタを勉強しているのですが、
for文で上記のようなものが出てきて、意味が分からず困っています。
*pで*p != NULL と同じような意味になるみたいなのですが…。
どうしてそのような意味になるのでしょうか?

ちなみにsとpはポインタで、
sには配列(入力した文字列)の先頭アドレスが入っています。
pは文字列を指していて○○○○○NULL ←になるから上記のような条件で
回るんだろうなぁとはなんとなく考えているのですが。

Aベストアンサー

念のため:
ヌルポインタは「ビットパターンとして」0 じゃないかもしれませんが, ソースプログラムにおいて「ポインタが要求される場面」で「0」とあれば, それは「ヌルポインタ」です.
もうちょっと厳密に書くと「整定数 0」はヌルポインタに変換される.

Q「char* p」と「char *p」は何が違うのでしょうか

「char* p」と「char *p」の違いを教えてください。

Aベストアンサー

同じ意味です。
ただ、
char* p, q;
と書いた場合、一見char*型のpとqを定義しているように見えるかもしれません。
しかし、実際はchar*型のpとchar型のqを定義しています。
意図とは違うことが起きるかもしれません。

したがって、私は、型名の最後ではなく変数名の頭に*を付ける
書き方を採用しています。

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Qchar *(*)[3];について

#include <iostream.h>
main(){
char *(*pp)[3];
printf("%lu", sizeof(char*));
printf(" pp%lu", pp);
printf(", ++pp%lu", ++pp);
}

これを実行して
4 pp6660000, ++pp???????
のように表示されたときに、???????の部分が何になるか考えました。
ppはchar[3]を指すポインタのポインタだから、ppをインクリメントすれば、「char[3]を指すポインタ」の大きさだけ大きくなるはずだから、「char[3]を指すポインタ」の大きさである4バイト大きくなるはずだから
4 pp6660000, ++pp6660004
になると思いました。
どこを勘違いしていてどう考え直せばよいか教えて下さい。

Aベストアンサー

pp は、3コのポインタの配列へのポインタです。
ポインタのサイズが4バイトの時、
pp をインクリメントすると12バイト増えることになります。

例えば、次の様に書くとわかりやすいと思います。
#include <cstdio>

using namespace std;
// CHAR3 は、3のサイズを持つchar の配列
typedef char CHAR3[3];

int main(){
CHAR3 *pc3;//pc3 は、char[3]を指すポインタ
char test[3];
pc3=&test;
printf("%p\n",pc3);
pc3++;
printf("%p\n",pc3);//+3(サイズ分)される

CHAR3 **ppc3;//ppc3 は、char[3]を指すポインタのポインタ
ppc3=&pc3;
printf("%p\n",ppc3);
ppc3++;
printf("%p\n",ppc3);//+4(ポインタサイズ分)される

return 0;
}

pp は、3コのポインタの配列へのポインタです。
ポインタのサイズが4バイトの時、
pp をインクリメントすると12バイト増えることになります。

例えば、次の様に書くとわかりやすいと思います。
#include <cstdio>

using namespace std;
// CHAR3 は、3のサイズを持つchar の配列
typedef char CHAR3[3];

int main(){
CHAR3 *pc3;//pc3 は、char[3]を指すポインタ
char test[3];
pc3=&test;
printf("%p\n",pc3);
pc3++;
printf("%p\n",pc3);//+3(サイズ分)される

CHAR3 **ppc3;//p...続きを読む

Qfgets((char*)&rbof,sizeof(ADR),fp) != NULL )

第2種情報処理技術者試験 平成7年春 午後 問7
http://www.bohyoh.com/ITEE/C/1995A07.html


中盤の
「while (fgets( (char*)&rbuf , sizeof(ADR), fp )!= NULL ) 」
が読めません

(char*)&rbuf , sizeof(ADR), fp
ファイルポインタからsizeof(ADR)サイズの分だけ取り出した文字を変数(char*)&rbufにほおりこむ

これが自分なりの解釈です
ですが「(char*)&rbuf」が意味不明。。。


根本的に解釈が間違っているのだと思います


詳しくわかる方教えてください

Aベストアンサー

rbufはADR型の構造体です。

&rbufは、ADR型の構造体rbufの実体へのポインタです。

つまり「&rbuf」は「(ADR *)&rbuf」です。

fgetsの引数は「char *」「size_t」「FILE *」ですから
fgets(&rbuf,sizeof(ADR),fp)
と書くと「char *」であるべき引数に「ADR *」を渡す事になります。

すると、コンパイラは「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」って言って、エラーになります。

なので「&rbufはADR *じゃなくて、char *だと思ってくれ」と書く必要があります。それが「(char *)&rbuf」と言う書き方です。

これを「型キャスト」と言います。

以下の例を参考に、考えてみて下さい。

typedef struct {
  (略)
} ADR;
(略)
  union PTR {
    char *char_ptr;
    ADR *adr_ptr;
  } ptr;
  ADR rbuf;
(略)
  ptr.adr_ptr = &rbuf;
(略)
  fgets(ptr.char_ptr,sizeof(ADR),fp);

この例は、ADR *とchar *を共有する共用体「ptr」を使用し「rbufのポインタ」を「ADR *型のadr_ptr」で受け取り、そのポインタを「char *型のchar_ptr」で参照しています。

つまり「型キャストを使用しないで書くと、上記のように共用体を使うなど、面倒な事をしなきゃなんない」のです。

これが、型キャストを使えば、
typedef struct {
  (略)
} ADR;
(略)
  ADR rbuf;
  fgets((char *)&rbuf,sizeof(ADR),fp);
だけで済んじゃうのです。

rbufはADR型の構造体です。

&rbufは、ADR型の構造体rbufの実体へのポインタです。

つまり「&rbuf」は「(ADR *)&rbuf」です。

fgetsの引数は「char *」「size_t」「FILE *」ですから
fgets(&rbuf,sizeof(ADR),fp)
と書くと「char *」であるべき引数に「ADR *」を渡す事になります。

すると、コンパイラは「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」って言って、エラーになります。

なので「&rbufはADR *じゃなくて、char *だと思ってくれ」と書く必要が...続きを読む


このカテゴリの人気Q&Aランキング

おすすめ情報