教えて!gooグレードポイントがdポイントに!

C言語を勉強している者です。以下の問題を解いてみたのですが、
エラーは特にないですし、実行結果も正しいものが表示されるのですが、フリーズされてしまい、表示画面が固まってしまいます。
また、問題文の沿って答えを出したいのですが、(3)のあたりが題意に沿えていないように感じます。
この2つのことで困っております。差し支えなければ、どなたかアドバイス頂けるたら幸いです。


(問題)以下の条件と、実行結果の例をもとにして、キーボードから入力した文字列を反転させるプログラムを作りなさい。
(1) 文字列の長さの最大値は16文字。
(2) キーボードから入力された文字列を、その長さ+1の配列変数をmalloc()で生成させて代入する。
(3) (2)で生成させた配列に、入力させた文字列を反転させたデータを入れる。
(4) 結果を出力する。
(5) 生成したメモリを、free()で開放する。

期待される実行結果の例
文字列を入力(最大16文字):ABCDE ← キーボードから入力
EDCBA




(私が作成したもの)
#include<stdio.h>
#include<stdlib.h>

#define SIZE 17

void main() {
char s[SIZE];
char *p = NULL;
p= (char*)malloc(sizeof(char)*SIZE);
printf("文字列を入力(最大16文字):");
scanf_s("%s", s,SIZE);
p = s;
while (*p!='\0'){
p++;
}

while (--p >= s) {
putchar(*p);
}
putchar('\n');

free(p);
}

教えて!goo グレード

A 回答 (2件)

1.配列sのi番目の要素(文字)はs[i]でアクセスできる。


2.同様にmallocで確保した領域のi番目の要素はp[i]でアクセスできる。
 ポインタ変数pの値を変更する必要はない。
3.例えばsに3文字入力した場合、最終文字はs[2]に格納されている。
 最終文字位置はstrlenを使用すれば得られる。
4.反転は、3の例で、s[2]~s[0]をp[0]~p[2]へコピーすれば良い。
 forやwhileを使用。
5.3の例で、p上のデータを文字列データとするためにp[3]に'\0'をセットする。
6.pを配列の先頭とする文字列をprintfで表示させる。
    • good
    • 0

>p= (char*)malloc(sizeof(char)*SIZE);


この時点で、「その長さ+1の配列変数をmalloc()で生成させて代入する。」ではありません。
一次受けとしてのchar s[SIZE]は、おそらく正しいでしょうが…。

で、確保したメモリへのポインタは
>p = s;
の時点で消失します。(確保したメモリブロックはそのまま)

なので、
>free(p);
はauto変数に対して実行していることになります。
(malloc()で確保した時のメモリブロックへのポインタではありません)
malloc()で確保した領域はそのままになっていますので、巷でよく言われる「メモリリーク」という不具合になります。
# 今時のまともなOSならそのままプログラムが終了するので問題にはなりませんけども。


>(2) キーボードから入力された文字列を、その長さ+1の配列変数をmalloc()で生成させて代入する。
は、(1)で入力を受けた配列をstrlen()なりで長さを取得、'\0'の分のメモリも込み(+1)でmalloc()で動的確保せよ。
ということかと。
代入するという記述がいまいち謎ですが。(1)で受けた内容をコピーしろ。ということでしょうかねぇ。(3)からすると意味が無いような気もしますが。

>(3) (2)で生成させた配列に、入力させた文字列を反転させたデータを入れる。
(1)の配列の内容を前後反転した状態で(2)で確保した領域に格納せよ。
ということでしょう。(おそらく問題のキモなので、どのようにやるのかは自分で考えてみてください)
# まあ、よくある問題なのでWeb検索とかで見つかるとは思いますけど。

>(4) 結果を出力する。
putchar()でもputs()でもprintf()でもいいでしょう。
# ただし、putchar()以外は文字列として正しく格納されているのが前提ですけど。

>(5) 生成したメモリを、free()で開放する。
そのまま…ですね。
前提として、(2)で受けたポインタが指している先が変わっていないこと…が前提になると思いますが。
# なのでポインタ変数pに対して操作は行わない方がよい。(やるならちゃんと元のアドレスを指すようにしましょう)
    • good
    • 1

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

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

教えて!goo グレード

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

人気Q&Aランキング