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

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

ただいまの
回答率

90.76%

  • C

    3461questions

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

動的配列についての動作

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 146

Rivia

score 11

動的配列について最近知りました。
思い通りに動作しないので助言お願いします

#include<stdio.h>
#include<stdlib.h>

int main(void){

    int i;
    int *heap;
    heap = (int*)malloc(sizeof(int)*10);
    for(i = 0;i<sizeof(heap);i++){
        heap[i] = i;

    }

    printf("%d",heap[i]);

    heap = (int *)realloc(heap,sizeof(int)*15);

    for(i = 0;i<sizeof(heap);i++){
        heap[i] = i;

    }

    printf("\n\n\n");
    printf("%d",heap[i]);
    free(heap);

    return 0;
}


イメージ説明

理想とする画面:
10

15

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+1

こんにちは。

恐らく2種類の間違いがあります。
まず、sizeof演算子は、変数自体のバイト数を返却します。
heapはポインタです。ポインタのサイズは32ビット・ビルドでは4バイト(=32ビット)、64ビット・ビルドでは8バイト(=64ビット)です。ですので、恐らく4か8になります。

次に、for文はiの初期設定i=0→継続条件判定i < sizeof(heap)→ループ内の処理heap[i] = i;→次処理i++→継続条件判定i < sizeof(heap)→...と進みます。
つまり、sizeof(heap)=4、i=3の時は、heap[3] = 3;i++4 < 4でループを抜けます。
そして、printf("%d",heap[i]);は、printf("%d",heap[4]);となりますが、heap[4]には値を設定していませんので、不定値が表示されます。

なお、heap[4]は今回はたまたま0でしたが0になることも期待しない方が良いです。処理系によって異なります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 23:23

    ありがとうございます。
    for文について勘違いしていました。
    そしてsizeofについても詳しく知ることができて大変感謝しております
    ですが。そうなると要素数の確認はどうすればいいのでしょうか。
    よろしければご鞭撻ください

    キャンセル

  • 2017/09/16 23:30

    >要素数の確認・・・intの配列として扱うのであれば最初は10,realloc()の後は15ですが・・・もし、確保した領域のポインタを関数などに渡すのであれば、渡された方では領域のサイズが分からないのでパラメータなどを使って、教えてやる必要があります。

    キャンセル

  • 2017/09/16 23:34

    C言語の場合は、残念ながらコンパイラはmallocで獲得した領域の要素数を管理してくれません。
    要素数を別途プログラムで管理するしかありません。今回の場合は、10や15を何か変数に入れて要素数として管理するのです。
    例えば、ポインタと要素数変数を構造体で管理するなどですね。
    以下の処理を適切な関数に分けて書くイメージです。

    // 管理領域の定義(C++になれているのでC言語だとちょっと違うかも。)
    struct dyn_array
    {
      int* heap;
      int count;
    };

    // 管理領域獲得
    dyn_array array;
    // 初期化
    array.heap=NULL;

    // 動的配列獲得
    array.count=15;
    array.heap=(int*)realloc(array.heap, sizeof(int)*array.count);

    ちなみに、C++ならdyn_arryの中に初期化やrealloc()的な処理を記述できるのでプログラムがすっきりします。

    キャンセル

  • 2017/09/16 23:53

    う~ん、理解力が足りていないのか、いまいち分かりません。
    mallocでは要素数を管理してくれないことと、
    管理するプログラムを別に作ることの意図までは分かるのですが
    なぜそのプログラムで要素数を管理することが出来るのかがいまいち。。。

    キャンセル

  • 2017/09/17 00:06 編集

    array.countに15を入れてます。例えば、各要素をfor文で列挙したい時は、下記処理でできます。
    for (int i=0; i < array.count; ++i) printf("[%d] %d\n", i, array.heap[i]);
    array.countが10の場合でも同じプログラムで対応できます。

    このようにheapとcountをセットにしてハンドリングすれば多少楽になります。
    関数に渡す際もいちいちheapとcountを別々に渡さなくていよいです。
    動的配列を複数渡したい時などに効いてきます。

    キャンセル

  • 2017/09/17 00:16

    なるほど!二つとも自分で入力してあげるのですね!
    そしてそれを構造体でまとめてあげると、、、
    分かりやすい説明ありがとうございます!
    わざわざお時間いただきありがとうございました

    キャンセル

0

パッと見ループ抜けてから i 使ってるからじゃないですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 23:24

    ループを抜けたときiはループ終了後の値になっているのではないのですか?
    だからループのたびに初期値を決めるのだと思っておりましたが

    キャンセル

  • 2017/09/16 23:26

    ループ内で使われた値に 1 足したものになっていると思います。
    ++ した結果、ループ条件から外れた時にループが終わるので。

    キャンセル

0

やはりこうなりましたか、前回の質問の方の私の回答を参考に下さい。

ちなみに、もうひとつ。ループを終了した時点においてカウンタ変数iは添え字の範囲の外になっていることに注意です。(0から9まで数え上げていったとしたら、ループ終了時には10となっている)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 23:25

    前回に続き回答ありがとうございます!
    for文について勘違いしていました。
    気づかせていただきありがとうございます。
    では要素数はどうやって確認すればいいのでしょうか
    是非よろしければ教えてください

    キャンセル

  • 2017/09/16 23:28

    mallocで確保されたバイト数を事後的に調べる万能な方法はありません。malloc時に使った引数を継続的に記録し続け、必要に応じて使うしかありません。

    キャンセル

  • 2017/09/16 23:35

    それはプログラムをみてバイト数を確認するということでしょうか。。。
    それではmalloc関数を使ってバイトを確保するときにはコメント文は絶対必要ですよね

    キャンセル

  • 2017/09/16 23:40

    意味が分かりませんが、「プログラムソース記述の段階で確認するしかない」という意味ならばその通りです。いずれにしろ動的に(プログラム実行中に)確認することはできません。引数の値を変数に格納しておくなりしておかないといけません。

    キャンセル

0

sizeof(heap)は、malloc()で確保したサイズではなく、ポインタのサイズです(4or8)。なので、意図した動きではないと思います。また、他の方の指摘にもあるようにprintf("%d",heap[i]);のiは(確保したメモリ内にありますが)数値を入れた所ではないデータを表示すると思います。・・・たまたま0だった^^

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 23:27

    malloc関数及びrealloc関数についてあまり理解が及んでませんでした。
    色々なサイトをめぐり学んでいるのですが、未だに理解できません・・・

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    .gitignoreで特定の文字列を含むファイルを除外するには?

    前提・実現したいこと WEBデザイナーでクライアントワークを担当しています。 SourceTreeを使用しています。 .gitignoreで相談があります。(.gitig

  • 解決済

    swift3 ボタンのsetTitleについて

    ボタンのタイトルをユーザーが変更した時 文字の長さを全て表示したい場合 ボタンのwidthを文字数に合わせて大きくしたいのですが 可能でしょうか? 色々調べたのですが載

  • 解決済

    SQLパラメーター式テーブルの値をand検索する

    実現したいこと fruit_id : 1 -> apple fruit_id : 2 -> mikan fruit_id : 3 -> banana テーブル名 : f

  • 解決済

    visual studio for mac のコンソールでキーボード入力がしたい

    前提・実現したいこと C#の勉強を始めようと思ってその過程でvasual studio for mac を使用しています。プログラミング初心者です。 発生している問題・エラ

  • 解決済

    main(int argc, char *argv[])の書き方

    int mainx(int argc, char *argv[]);と宣言されています。 実装部 int mainx(int argc, char *argv[]){ }

  • 解決済

    IntelliJ IDEA でKotlinの実行ができない

    実現したいこと IntelliJ IDEAで Kotlinのプログラムを実行したいです。 しかしエラーが表示されてしまいます。 ソースコード package sampl

  • 解決済

    python-shogiの使い方

    python3(anaconda)にpython-shogiモジュールを入れて shogi.CSAを使いたいのですがエラーがでて使えません。どのようにすればよいのでしょうか sho

  • 解決済

    ビットの回転について

    前提 現在書籍でc言語を学習している者です。 その書籍の演習問題は解答が存在しておらず(著者の意図的に) 学習を進めることが困難な時があるので、問題のヒント等を教えていただきたいで

同じタグがついた質問を見る

  • C

    3461questions

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