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

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

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

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

Q&A

解決済

2回答

1491閲覧

c言語で動的確保した領域の開放について

K.M.PEANUTS

総合スコア40

C

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

0グッド

0クリップ

投稿2021/04/19 05:25

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MAX_LEN 100 //文字配列のサイズ(入力文字列の最大長さ+1) 6 7//文字列の画面出力用関数 8void output_strings(char **array_p, int m) 9{ 10 int i; 11 printf("%d\n", m); 12 for(i=0; i<m; i++) { 13 printf("%s\n", array_p[i]); 14 } 15} 16 17 18int main( void ) 19{ 20 int i,j; 21 int n; //文字列の個数 22 char data[MAX_LEN]={}; //入力用文字列 23 char **str_p; 24 char *p; 25 26 //文字列の個数の入力 27 printf("Number of strings -> "); 28 scanf("%d", &n); 29 30 //文字列へのポインタを格納するポインタ配列の動的確保 31 str_p = (char **)malloc(sizeof(char *) * n); 32 33 //iii〜vの処理 34 for(i=0; i<n; i++) { 35 printf("Input strings -> "); 36 scanf("%s", data); 37 printf("%s\n", data); 38 str_p[i] = (char *)malloc(strlen(data) + 1); 39 strcpy(str_p[i], data); 40 41 } 42 43 44 //文字列の画面表示 45 printf("\nBefore sorting\n"); 46 output_strings(str_p, n); 47 48 //文字列を長さが短い順番に並べ替え 49 char *tmp; 50 for(i=0; i<n-1; i++) { 51 for(j=i+1; j<n; j++) { 52 if(strlen(str_p[i])>strlen(str_p[j])) { 53 tmp = str_p[i]; 54 str_p[i] = str_p[j]; 55 str_p[j] = tmp; 56 } 57 } 58 } 59 60 //並べ変えた文字列の画面表示 61 printf("\nAfter sorting\n"); 62 output_strings(str_p, n); 63 64 //動的確保した領域の開放 65 free(str_p); 66 for(i=0; i<n-1; i++) { 67 free(str_p[i]); 68 } 69 70 return 0; 71}

上記のコードで何かおかしいところはありますか?
一応画面表示したいことは全てできて警告なども出ないのですが、一番最後の動的確保した領域の開放で、for文のループ条件がi<n-1になる理由がわかりません。
mallocで動的確保したのはstr_p[n-1]までだと思うのでここでのfor文のループ条件はi<nではないでしょうか?しかしi<nと書くと動的確保してない領域まで開放している開放しているという内容のメッセージが出てきてしまいます。そこで、このコード自体どこかおかしいのではないかと疑ったのですが、i<n-1となる理由を教えてください。

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

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

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

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

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

dodox86

2021/04/19 07:27

質問の前提が分かりづらいようです。このコードは質問者さんが書いたものではないのですか? 自分で書いた上で、「おかしいところはないか?」というレビューなのでしょうか。それとも、他人が書いたコードで理解できないところがあり、その部分が「for文のループ条件がi<n-1になる理由がわかりません。」と言うことなのでしょうか。
guest

回答2

0

メモリ領域については、すでに回答がついているので触れませんが

i<n-1となる理由

入れ替えるアルゴリズムを考えれば全てをサーチするのではなく、その一つ前までをサーチするので十分ということはご理解できるのではないでしょうか。

投稿2021/04/19 07:08

t_obara

総合スコア5488

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

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

maisumakun

2021/04/19 07:10

入れ替えの話ではなく、最後の解放で「i<n-1」となっているのはなぜか、という質問ではないでしょうか?
t_obara

2021/05/10 01:27

確かに、読み間違えていました、ご指摘ありがとうございます。
guest

0

ベストアンサー

上記のコードで何かおかしいところはありますか?

解放の順番が逆です。先にstr_p[i]を解放してからfree(str_p)としなければいけません。

投稿2021/04/19 05:32

maisumakun

総合スコア145184

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

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

maisumakun

2021/04/19 05:33

free(str_p)としたあとにstr_p[i]へアクセスした場合、何が起きるかは保証されません(メモリの中身が破壊されていたり、アクセスした時点でエラーになったりしても文句は言えません)。
maisumakun

2021/04/19 07:10

> しかしi<nと書くと動的確保してない領域まで開放している開放しているという内容のメッセージが出てきてしまいます。 たまたまstr_p[n-1]だけ破壊された状況だったのでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問