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

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

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

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

669閲覧

静的配列を持つ動的配列を作成したい

s8079

総合スコア36

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/06/20 07:59

編集2021/06/20 08:08

前提・実現したいこと

静的配列を持つ動的配列を作成したいです.

下記のソースコードでは,静的配列を構造体として定義しておくことで実現しています.
しかし,配列一つのために構造体を定義するのは面倒に感じました.
そこで,下記ソースコードと同じ動作を構造体を用いずに再現したいです.

C

1#include <stdio.h> 2#include <stdlib.h> 3typedef struct { 4 char str[32]; 5} STR; 6int main() { 7 STR str = { "ABC" }; 8 STR *data; 9 data = (STR *)malloc(sizeof(STR) * 5); 10 data[0] = str; 11 printf("%s\n", data[0]); 12 free(data); 13 return 0; 14}

試したこと

下記ソースコードは試しに作成したものになります.
こちらはエラーが出て動作しません.
エラーはchar**char (*)[]を変換できないといった内容のようです.
一度構造体を定義するしか解決方法はないのでしょうか?
アドバイスをいただけると助かります.

C

1#include <stdio.h> 2#include <stdlib.h> 3int main() { 4 char str[32] = "ABC"; 5 char (*data)[]; 6 data = (char **)malloc(sizeof(char *) * 5); 7 data[0] = str; 8 printf("%s\n", data[0]); 9 free(data); 10 return 0; 11}

エラーメッセージ

prog.cc: In function 'int main()': prog.cc:6:16: error: cannot convert 'char**' to 'char (*)[]' in assignment 6 | data = (char **)malloc(sizeof(char *) * 5); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | char** prog.cc:7:15: error: invalid use of array with unspecified bounds 7 | data[0] = str; | ^ prog.cc:7:15: error: invalid use of array with unspecified bounds 7 | data[0] = str; | ~~~~~~^ prog.cc:8:30: error: invalid use of array with unspecified bounds 8 | printf("%s\n", data[0]); | ^

補足情報(FW/ツールのバージョンなど)

C99

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

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

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

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

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

guest

回答2

0

こんなのがやりたいんかな?

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4 5int main() { 6 7 char* data[5]; 8 9 char* body = (char*)malloc(26); 10 strcpy(body, "abcdefghijklmnopqrstuvwxy"); 11 for ( int y = 0; y < 5; ++y ) { 12 data[y] = body + (5*y); 13 } 14 15 // できたかな? 16 for ( int y = 0; y < 5; ++y ) { 17 for ( int x = 0; x < 5; ++x ) { 18 printf("%c ", data[y][x]); 19 } 20 printf("\n"); 21 } 22 return 0; 23}

投稿2021/06/20 08:35

episteme

総合スコア16612

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

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

0

ベストアンサー

質問者のやろうとしているコードから型の合わない部分を調整するとこのように書けなくはないですね。

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char str[32] = "ABC"; char (*data)[32]; data = (char (*)[32])malloc(sizeof(char[32]) * 5); memcpy(data[0], str, 32); printf("%s\n", data[0]); free(data); return 0; }

型の大きさ

プログラム内で代入やら何やらをするにあたって大きさの情報は重要で、配列の大きさを与えずに宣言した場合には「不完全型」として処理されます。 不完全型のままでは出来ることが制限されます。

質問の事例における char (*data)[]; は大きさのわからない配列を指すポインタになっています。

配列型の制約

配列は「それ自体は値として扱えない」という制限があり、配列全体をコピーするために代入文では出来ないことになっています。

なので C では標準的な関数として memcpy などが用意されているのです。

それでも配列を式に書くと

配列は値としてあつかえませんがそれでも式中にあえて配列を与えた場合、それはその配列の先頭要素を指すポインタに「暗黙に型変換される」というルールがあります。

つまり質問者が試して失敗した事例における data[0] = str; では data[0] は大きさのわからない要素ですし、 str は (配列ではなく) str の先頭要素を指すポインタなので型が合わないという問題として検出されてしまいます。

解決策

冒頭で私が示したコードは大きさのわからない部分を明示的に与えています。

構造体であれば構造体の型は自分の大きさを知っているのであらゆる箇所で大きさを明示する必要はありませんが、そうでない場合には処理の各所に適切に大きさを与えないと破綻してしまうのです。 そして間違った値を指定してもコンパイル時に検出できないこともあります。

つまり、やりようによっては出来なくはないですが、 C の習慣からすると面倒なのであまりやらないでしょうというのが質問に対する答えです。

投稿2021/06/20 08:31

SaitoAtsushi

総合スコア5675

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

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

s8079

2021/06/20 09:14 編集

大変わかりやすい解答ありがとうございます. 不完全型という用語は初めて聞きましたが,配列の大きさが不明というのは察していました. しかし,その指定方法がわからず困っていたところです. 今回は配列の大きさを含めた明示的な型指定を行いたいと思います. 安全な設計を重視するなら構造体を定義すべきでしょうが… あと,配列コピーに関してはただのミスです…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問