質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

682閲覧

関数にポインタを渡すとランタイムエラーになります。

err0r

総合スコア20

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/04/16 17:21

下記練習問題を解いているのですが、このコードを実行するとランタイムエラーになります。ポインタ*strの部分を配列str[256]にすると正しくコードが実行されます。
なぜポインタを関数に渡すとランタイムエラーになってしまうのでしょうか?

問.文字列sを受け取って、文字cが含まれていれば、そのアドレスを返す関数を作成せよ。

#include <stdio.h> char *str_chr(const char *s, int c){ char *p = NULL; while(*s++){ if (*(s-1) == c){ p = (s-1); break; } } return p; } int main(void){ char *str; int ch = 'c'; printf("文字列を入力\n"); scanf("%s", str); printf("%cはアドレス%pにあります。", ch, str_chr(str, ch)); } ```

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

文字列を格納する領域が用意されていないから。

投稿2019/04/16 18:11

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

err0r

2019/04/17 06:16

Char* pでは文字列を格納する領域まで用意されると思っていました。ありがとうございます。
episteme

2019/04/17 09:27

されるわけないぢゃん。大きさがわからんのやから。
guest

0

ランタイムエラーだけでは情報が足りません。「どんな」ランタイムエラーなのか、エラーコードなりメッセージなりをきちんと提示しなければ意味がありませんよ。

さてプログラムを追いかけると、

C

1char *str_chr(const char *s, int c){ 2 char *p = NULL; 3 while(*s++){ 4 if (*(s-1) == c){ 5 p = (s-1); 6 break; 7 } 8 } 9 return p; 10}

ポインタ p は NULL ですから、p の示す先へアクセスすることは許されていません。
その状態でアクセスしたのですからエラーになったのでしょう。
ポインタはあくまでもメモリ上にある領域を指し示すためのポインタであって、領域が存在しないのに使ったり、領域を超えてアクセスするような使い方をしてはいけないのです。

ついでにいえば、このコードには別の問題が少なくとも二つあります。

  1. char と int を比較するのにキャストをしていない
  2. 与えられたパラメータ S が NULL だったり、空文字列だった場合を考慮していない

投稿2019/04/16 23:53

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

WoodenHamlet

2019/04/17 05:10

該当部ではポインタの代入しかしてないのでは?
err0r

2019/04/17 07:25

情報不足で失礼いたしました。ランタイムエラーは下記になります。 Runtime error(Exit status:139(Invalid memory reference)) charとintの比較部分ですが、キャストを入れてみました。 if (*(s-1) == (char) c) としても if (*(s-1) == (int) c ) としても同じ結果になりました。 sはchar型のポインタなので、(int) cとした場合、文字(c)と文字コード(99)を比較する事になり、 結果が変わると思っていたのですが、そうなりませんでした・・・。
tacsheaven

2019/04/17 08:28

キャストしないと警告出すコンパイラもあるのです。 エラーについては他の方が的確な指摘をされているので、そちらを参考にどうぞ。
guest

0

ベストアンサー

ポインタはアドレス値を持っているだけで、領域を持っているわけではありません。
どこかに確実に確保されている領域のアドレスを指し示すことで初めて使えます。
strをポインタとして扱いたいなら、配列を用意してそのアドレスを代入してあげることで使えるようになります。

c

1char work[256]; 2char *str; 3str = work;

投稿2019/04/16 23:45

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

err0r

2019/04/17 06:18

修正案まで提示していただいてありがとうございました。教えていただいたコードに変更すると、正しく動作するようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問