• ベストアンサー

ポインタを使ったプログラムのミスでPCは大丈夫?

つまらない質問かとは思いますが、よろしくお願いします。 Cを学習している途中のですが 参考書を読み進め、ポインタの概念に関する章まですすみました。 ポインタへの理解を深めるために 簡単なプログラムを作っているのですが。 *p + i と *(p + i) この二つでは動作が違うために コンパイルはできたものの、暴走をしてしまいました。 iの値がどんどん増えていき、*pに何かを代入するようなプログラムだとしたら メモリにどんどん書き込まれていくと思うのですが その際に、インターネットエクスプローラやアウトルックなどの、ソフトを立ち上げていた場合 影響はないのでしょうか? ソフトを立ち上げていなくても、PCが起動している限り 何らかの値がメモリに保存されていると思うのですが (pcには詳しくないので、違っていたらすみません) 暴走したプログラムが、パソコン内部のなにかに影響を及ぼして PCが使えなくなる!壊れてしまう!? なんてことはあるのでしょうか? これからどんどんPCの知識を得ようと思っているので 書籍など読めばいずれはわかるとは思うのですが パソコンの生命が脅かされるほどの問題だったら!? (だとしたら、参考書に危険だよ!と書いてあるとは思いますが^^;) と思うと心配になったので、質問させていただきます よろしくお願いします。

  • urecy
  • お礼率43% (38/87)

質問者が選んだベストアンサー

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.3

とてもするどい質問だと思います。 現在の Windows とか Linux や Mac OSX といった「近代的な OS」では、プログラムの中から(普通に)アクセスできるメモリは、他のプログラムに影響を与えない(アクセスできない)ようになっているので、自分が作ったプログラムのバグのせいで、同時に実行していた他のプログラムが落ちるということは、一応、起きない事になっています。 ただし、実際にはメモリの量には限りがあって、それを複数のプログラムが分け合って使っているので、あるプログラムがすごーく沢山メモりを使うと、他のプログラムが使うメモリが足りなくなって、結果的に落ちてしまう、ということは起きます。 いずれにせよ、どんなプログラムを書いても、ウイルスのような悪さは出来ても、ハードウェアを壊すような事は、どんなに頑張ってもできませんので、安心してプログラムを書いてください。

urecy
質問者

お礼

早速の回答ありがとうございます。 >他のプログラムに影響を与えない(アクセスできない)ようになっているので 他のアプリケーションにも影響がないのですね、安心しました。 解りやすい回答ありがとうございました! 引き続き学習に励んでいきます。

その他の回答 (2)

  • f_attck
  • ベストアンサー率33% (40/118)
回答No.2

まず始めに、PCが壊れることは無いと思います。 基本的にユーザが使用できるメモリ空間とシステムが使用する メモリ空間は違います。 システムが使用するメモリ空間、つまりOSが使用するメモリ空間 なんですが、基本的にはユーザプロセスから触ろうとした場合には segmentation faltとなって、そのプロセスが異常終了するはずです。 また、メモリとはRAMですので電源ONからOFFまでの間に 使用できる記憶素子です。 ですので、再起動すれば問題ないです。 (メモリリーク等の対応は、これでできます)

urecy
質問者

お礼

早速の回答ありがとうございます。 >基本的にユーザと、システムが使用するメモリ空間は違います。 そうなんですかー知りませんでした。勉強になります。 その解決と同時に、他の悩みが出たのですが (osだけでなく、他のソフトなどへの影響) No.3の方がそこも回答されていたので 2番目の良回答とさせていただきました。 解りやすい回答ありがとうございました!

  • guttie5
  • ベストアンサー率44% (4/9)
回答No.1

使用しているコンパイラは何でしょうか? 例えば、デバッガを使用している場合は、大抵、そのデバッガがワーク領域を確保しているので、暴走する事はありません。

urecy
質問者

お礼

早速の回答ありがとうございます。 パソコン用語に詳しくないので、デバッガの意味が解らないのですが 後ほど用語辞書で調べてみます。 今回の件では、PCに影響が無いと言うことで理解しました。 ありがとうございました。

関連するQ&A

  • 関数にポインタを渡して動的確保する時について

    どうにも動的確保について間違っている気がするのでお尋ねいたします。 よくメモリを動的に確保する場合に私は次のようなプログラムを書きます ポインタを用意する(例えばint *p) mallocでメモリ確保 ポインタを関数に渡す(Func(p)) 関数側でreallocし、値を代入する(p=(int *)realloc(p,sizeof(int)*num)) 関数呼び出し側で、その値を使う しかし、この方法を使うとどうにも関数を呼び出した際のポインタ(p)と、reallocした後のポインタ(p)の値が違うことがあり、値が不定になることがあります。 (reallocのメモリの確保の仕方のせいでしょうか) この使い方は恐らくどこか間違っていると思うんですが、いまいち納得のいく解決策が思いつきません。 例えばポインタを引数ではなく戻り値として得ればできますが、2つ以上のポインタについてはできません。 何卒ご教授のほどをよろしくお願いいたします。

  • ポインタ配列のプログラムについて

    ポインタ変数の配列のプログラム #include<stdio.h> void main() { char *p[] = {"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE", "JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"}; int i,j; *p[0]=*p[2]; *p[0]=*p[2]; for(i = 0;i < 12; ++i){ printf("%2d 月:%s\n",i+1,p[i]); } for(i = 0;i < 12; ++i){ j = -1; do{ ++j; printf("%4x ",p[i]+j); } while (*(p[i]+j) != '\0'); printf("\n"); j = -1; do{ ++j; printf(" %c ",*(p[i]+j)); }while (*(p[i]+j) != '\0'); printf("\n"); } } について、このプログラムを最も大きい値(ASCIIの文字コードが最も大きい値)を出力するプログラムに変更したいのですが、ASCIIの文字コードが何なのかよく分かりません。分かる方いましたら教えてください。よろしくお願いします。

  • ポインタに ~0を入れること

    見かけたCのプログラムで、 ポインタに~0を代入するものを見ました。 そのプログラムをそのまま載せるのはわかりにくいので、 代わりに以下のプログラムを作って実行しました。 #include <stdio.h> int main(void) { char *pa[3]; int i; pa[0]=0; pa[1]=~0; pa[2]="Hello"; printf("sizeof(char*)=%d\n", sizeof(char*)); for(i=0; i<=2; i++) { if(pa[i]==NULL) printf("pa[%d] はNULLです。\n", i); if(pa[i]==(char*)0xFFFFFFFF) printf("pa[%d]は全ビット1です。\n", i); if(pa[i]==~0) printf("pa[%d]は~0です。\n", i); } return 0; } 結果 sizeof(char*)=4 pa[0] はNULLです。 pa[1]は全ビット1です。 pa[1]は~0です。 このプログラムはコンパイル時にエラーも警告も出ず、 動作も意図したとおりです。 pa[1]に入っている ~0 は、int型の定数なのでしょうか。 それならば、 pa[1]=~0; という代入や if(pa[i]==~0) という比較は 左辺はchar*型で右辺はconst int型であって型が異なりますが、 問題ないのでしょうか。 ~0は0の否定なので、全ビットは1なのでしょうけど、 int型(の定数)だと思います。 ~0というのは何か特別な値なのでしょうか。 ポインタに~0を入れるというのは、意味があるのでしょうか。 (例えば、「ポインタに0を入れるということは、ヌルポインタであって、ポインタとして無効なんですよ」のようなこと。)

  • ポインタ スペースを数えるプログラム

    入力した文章のスペースを数えるプログラムを作ってみました. ポインタをまだしっかり理解していないのですが,ポインタを使用 する場合,以下のようなプログラムで正しいですか? (オーバーフローなどについては対処していません.) #include<stdio.h> int main(void) { char str[80],*p; int i,count=0; gets(str); p=str; for(i=0;i<80;i++) { if(p[i]==' ') { count++; } } printf("%d",count); return 0; }

  • ポインタいついて教えてください

    ポインタがわかりません。 教えてください。 下の二つは、共に「100」を表記すると思いますが、 どこがどのように違うのですか。 また、f1()という関数をつくって、ここで scanfを使って、5つぐらい値を代入させて、 他の関数でこの値を使おうと思っています。 この場合下のどちらを使うのが、よろしいのでしょうか。 よろしくお願いします #include <stdio.h> int main(void) { int *p, q; q = 100; /* q に100を代入 */ p = &q; /* p にq のアドレスを割り当てる */ printf("%d", *p); return 0; } #include <stdio.h> int main(void) { int *p, q; p = &q; /* q のアドレスを得る */ *p = 100; /* ポインタを使ってq に値を代入する */ printf("%d", q); return 0; }

  • ポインタのポインタとrealloc

    先程関数による動的確保について質問させていただき、ヒントを与えていただいたのですが、そこからまた疑問が生じました。 テストプログラムを作ったのですが、何やら動作がおかしいみたいです おかしい部分を抜き出したソースは次のとおりです int main() {  int **p;  int i;  p = (int **)malloc(sizeof(int *));  *p = (int *)malloc(sizeof(int));  p[0]=0;  for(i=1;i<10;i++){   *p = (int *)realloc(*p,sizeof(int)*(i+1));   *p[i] = i;  }  free(*p);  return 0; } 関数部として作りたい部分をメインにして抜き出しました。 このようにするとreallocがメモリ領域を拡張してくれなく(?)、*p[i] = i;の部分でエラー終了します。 ポインタのポインタではなく、ポインタを用いた時は正常に動作するのですが、何がまずいのでしょうか。 もし宜しければお願いいたします。 ちなみに私は学部4年生で、プログラムの使用は大学の研究用レベルです。

  • ポインタのプログラムについて

    以下のプログラムを実行したとき、表示される値を余白に記述せよ。ただし、配列idataは1000番地から格納されているとする。また、表示結果*8**~*10**の箇所で、正しく計算された値のみ表示させるには、maxはいくらに設定すればよいか。という課題なんですが、実際にプログラムを作ってみてmaxの箇所を4にしてみたところ間違いと言われたので正しいmaxの値を教えて下さい。 #include<stdio.h> int main(void) { int iv,idata[]={2,4,6,8,10,12},*ip,i,max; iv=idata[0]; printf("*1*ivの値=%d\n",iv); ip=&idata[0]; printf("*2*ipの値=%p\n",ip); ip=&idata[1]; printf("*3*ipの値=%p\n",ip); ip=&idata[2]; printf("*4*ipの値=%p\n",ip); iv=*ip; printf("*5*ivの値=%d\n",iv); iv=*ip+3; printf("*6*ivの値=%d\n",iv); iv=*(ip+3); printf("*7*ivの値=%d\n",iv); max=4; *ip=0; for(i=0;i<max;i++){ printf("*8**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+1)=10; for(i=0;i<max;i++){ printf("*9**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+3)=20; for(i=0;i<max;i++){ printf("*10**(ip+%d)=%d\n",i,*(ip+i)); } ip=&idata[0]; printf("*11*ipの値=%p\n",ip); ip=ip+2; printf("*12*ipの値=%p\n",ip); iv=*ip+3; printf("*13*ipの値=%d\n",iv); iv=*(ip+3); printf("*14*ivの値=%d\n",iv); ++ip; printf("*15*ipの値=%p\n",ip); } ヒントは”正しく計算された値のみ”という部分らしいのですが、自分にはまったく分りませんでした。

  • ポインタのポインタの必要性

    書物によるとポインタのポインタの使用例として「ポインタの配列」はポインタを使ってアクセスすることができます。」[*]とありますが、どうしてポインタのポインタが必要なのかがいまいちピンと来ません。 どういう場合なのかを知りたく思っています。 [*]サンプルスクリプト ===================================================== char *mnthp[3] = {/* ポインタの配列の宣言 */ "January", "February", "March" }; char **p1;/* 「ポインタのポインタ」の宣言 */ int i, j; p1=mnthp;/* 「ポインタのポインタ」にポインタの配列 */ /* の先頭番地を設定 */ /***** 例1 *****/ for (i = 0; i < 3; i++) {/* 「ポインタのポインタ」の値を変えずに */ printf("%s\n", *(p1 + i));/* 相対的に文字列を出力 */ } ==> このようなことをしなくとも printf("%s", mnthp[i]); で値を参照出来ると思われる。 ===================================================== [*] http://www9.plala.or.jp/sgwr-t/c/sec10-4.html 宜しくお願い致します。

  • ポインタへの値の代入時の警告の原因

    私は現在、事務職をやっており、プログラミングとは全く別の畑に居ます。 真剣に転職を考えておりC言語を独学にて勉強中なのですが、ポインタの勉強中、どうしても理解できない点がありましたので質問いたしました。 ポインタを理解するために下記1~3のような処理をさせました。 1.文字変数s に 'a' を代入 2.ポインタp を宣言し、変数s のアドレスを代入 3.最終的にpの値を確認する。 #include<stdio.h> int main (void) { char  s; char  *p; s = ' a '; p = & s;        //←ここが9行目です printf (" pは %c です\n " , *p); return 0; } すると、 『 pは a です 』 と、期待通りの表示がされました。 次に、9行目を *p = s と書き換えた所、コンパイル時に 『値が割り当てられていないローカルな変数’p’に対して参照が行われました』 と言う警告が表示されました。 実行してみた所、 『pは a です』 と、結果は期待通りのものが表示されたのですが、この警告がなぜ表示されたのかが分かりません。 参考書を読んでも、このような(*p = sのような)書き方は載ってましたし、私自身、『「ポインタ変数pの値*p」に「変数sの値」を代入した。』と認識している為、間違いでは無いと考えております。 この警告がなされた原因について、どなたかご存知でしたら、宜しくお願いいたします。

  • 【なぜポインタを使うのか】

    私は、ポインタのメリット・デメリットを以下のように考えています。 ◆メリット メモリを多く確保しなければならないオブジェクトについて、コピー処理を行うことなく省メモリでインタフェースできる。 ◆デメリット ・関数内でしか使用しない非ポインタのローカル変数に比べ、  アクセス可能な場所が多くなってしまい、色んな箇所から値が変更されうる。(影響範囲の限定がしずらい) ・可読性が低くなる。(若いエンジニアはCの経験者は少なくっていくと思われるため、保守コストが若干割高になる) そのため、よっぽどメモリを多く使うようなオブジェクトでなければ、 (もしくは速度を重視する必要があるプログラムでなければ) 値渡しにしても良いのではと考えています。 しかし、度々目にするソースは、何でもかんでもポインタで処理しているものも多々見受けられます。 特に、int型のようなメモリを大量に使用しないものでも、ポインタで変数宣言しているケースもよく見ます。 なぜなのでしょうか? (熟練のC言語プログラマが、昔ながらの記述を踏襲しているというのはあるのかなと考えていますが)

専門家に質問してみよう