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

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

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

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

Q&A

解決済

4回答

2124閲覧

C言語 ポインタ配列の確保領域について

tekondo

総合スコア26

C

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

0グッド

0クリップ

投稿2017/07/11 15:11

###質問の詳細
mainで宣言しているポインタ配列を別の関数に引数として渡します。その時NULLすらも入っていない?ポインタの指定先の領域は呼び出した関数内ではポインタ配列を使って指定できないのでしょうか?質問がややこしくてすみません。具体的にいうと*args[]というポインタ配列に
*args[0} cd
*args[1] *
args[2] NULL
が格納されている状態で関数に引き渡してargs[3]にstrcpyで文字列をコピーしようとするとそこで異常終了しているみたいなんです。もともと何も格納していないargs[3]なので指定領域が存在していないのでエラーを起こしているというイメージであっていますか?そしてその時だと関数内でargs[3]に文字列を格納したい場合はmallocで動的に領域を確保するのが正しいのでしょうか?ソースコードも全体のプログラムの量が多いので問題の関数のみ載せます。 教えていただければ幸いです。よろしくお願いいたします。

###該当のソースコード

c

1void wild(char *args[256]){ 2 printf("wild start\n"); 3 char currentdir[512]; 4 char *stackchar[512]; 5 int i = 0; 6 int count = 0; 7 DIR *dir; 8 int stackint = 0; 9 int hoge = 0; 10 struct dirent *dp; 11 getcwd(currentdir,512); 12 printf("currentdir is %s\n",currentdir ); 13 for(i = 0;args[i] != NULL;i++){ 14 } 15 printf("args's number is %d\n",i); 16 for(count = 0;args[count] != NULL;count++){ 17 if (strcmp(args[count],"*") == 0) { 18 printf("serch *\n"); 19 hoge = count; 20 while(args[count + 1] != NULL){ 21 count++; 22 strcpy(stackchar[stackint],args[count]); 23 stackint++; 24 } 25 26 27 dir = opendir(currentdir); 28 if (dir == NULL) { 29 printf("opendir is not success\n"); 30 } 31 dp = readdir(dir); 32 while(dp != NULL){ 33 printf(" directry name is %s\n",dp -> d_name); 34 //ここが問題の箇所です。 35 strcpy(args[hoge],dp -> d_name); 36 hoge++; 37 dp = readdir(dir); 38 } 39 40 41 closedir(dir); 42 43 i = 0; 44 while (stackchar[i] != NULL) { 45 strcpy(args[hoge],stackchar[i]); 46 i++; 47 hoge++; 48 } 49 50 i = 0; 51 while (args[i] != NULL) { 52 printf("%s\n", args[i]); 53 i++; 54 } 55 } 56 } 57}

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

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

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

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

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

guest

回答4

0

pointer配列が実メモリにポイントする様に変更してみました。期待する答えが分かると良いのですが

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <dirent.h> 5 6void wild(char *args[256]){ 7 printf("wild start\n"); 8 char currentdir[512]; 9 char *stackchar[512] ={'\0'}; 10 DIR *dir; 11 int i = 0; 12 int count = 0; 13 int stackint = 0; 14 int hoge = 0; 15 struct dirent *dp; 16 17 getcwd(currentdir,512); 18 printf("currentdir is %s\n",currentdir ); 19 for(i = 0;args[i] != NULL;i++){ 20 } 21 printf("args's number is %d\n",i); 22 23 for(count=0; args[count] != NULL; count++){ 24 if (strcmp(args[count],"*") == 0) { 25 printf("serch * \n"); 26 hoge = count; 27 while(args[count + 1] != NULL){ 28 count++; 29 if (stackchar[stackint] == NULL) 30 stackchar[stackint]=(char*)calloc(64,sizeof(char)); 31 strcpy(stackchar[stackint],args[count]); 32 stackint++; 33 } 34 35 dir = opendir(currentdir); 36 if (dir == NULL) { 37 printf("opendir is not success\n"); 38 } 39 dp = readdir(dir); 40 while(dp != NULL){ 41 printf(" directry name is %s\n",dp -> d_name); 42 if (args[hoge] == NULL) 43 args[hoge]=(char*)calloc(64,sizeof(char)); 44 strcpy(args[hoge],dp -> d_name); 45 hoge++; 46 dp = readdir(dir); 47 } 48 49 closedir(dir); 50 51 i = 0; 52 while (stackchar[i] != NULL) { 53 if (args[hoge] == NULL) 54 args[hoge]=(char*)calloc(64,sizeof(char)); 55 strcpy(args[hoge],stackchar[i]); 56 i++; 57 hoge++; 58 } 59 60 i = 0; 61 while (args[i] != NULL) { 62 printf("%s\n", args[i]); 63 i++; 64 } 65 break; 66 } 67 } 68} 69 70void main(void){ 71 char *p[256] ={'\0'}; 72 char b1[64] = "cd"; 73 char b2[64] = "*"; 74 char b3[64] = "\0"; 75 p[0]=b1; 76 p[1]=b2; 77 p[2]=b2; 78 79 wild(p); 80}

投稿2017/07/12 04:16

A.Ichi

総合スコア4070

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

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

tekondo

2017/07/12 07:15

なるほどです。wild関数に引き渡す前の初期化で'\0'を入れておくと引数としてポインタ配列を渡しても大丈夫なんですね、ありがとうございます。
guest

0

もともと何も格納していないargs[3]なので指定領域が存在していないのでエラーを起こしているというイメージであっていますか?

あっています。

そしてその時だと関数内でargs[3]に文字列を格納したい場合はmallocで動的に領域を確保するのが正しいのでしょうか?

提示のコードを見た限りでは正しいです。
ただし、wild関数に渡している変数が、main関数が受け取った第二引数(argv)をそのまま渡しているのであるなら、間違いです。
その場合、argv配列の要素数がわからないので、そもそもその要素の領域(質問で言えば[3])が確保されているかわかりません。
もしかしたらC言語の定義の最大数が決まっているかもしれませんが、そういうのは聞いたことがないので(私が知らないだけかもしれませんが…)

投稿2017/07/11 23:35

ttyp03

総合スコア16996

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

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

tekondo

2017/07/12 09:01

そのまま渡しているのでダメですね、、、プログラム書き換えます。ご回答ありがとうございました。
guest

0

そもそも、argvの実体の要素数は幾つなんでしょうか?
仮引数に要素数を書いても無意味ですよ。char *argv[]と同じです。

要素数が4以上でargv[3]が存在している前提で、argv[3]=malloc(~)するか、
それをwild関数内でしか使わないのであれば、ローカル変数のアドレスを代入してもいいです。
つまり、char area[100]; argv[3] = area;とか。
ただ、コードを見るとmallocは必須ですね。

main()の第二引数のargvだったりすると、この場合要素数が3なので、そもそもargv[3]にアクセス出来ません。

C

1char *argv2[256]; 2int i; 3for(i=0;argv[i];i++) { argv2[i] = argv[i]; } 4以下では、argv2を使う。

とか

投稿2017/07/11 16:23

編集2017/07/11 16:27
otn

総合スコア84423

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

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

tekondo

2017/07/12 08:59

要素数が3なのでダメですね、、、プログラム書き換えます。ご回答ありがとうございました。
guest

0

ベストアンサー

こんにちは。

が格納されている状態で関数に引き渡してargs[3]にstrcpyで文字列をコピーしようとするとそこで異常終了しているみたいなんです。

初期化されていないポインタの指す領域へ文字列をコピーしようとしたわけですね。
初期化されていないため、そのポインタに設定されているアドレスは不定ですが、何か入ってます。その謎のアドレスのメモリへ文字列をコピーしようとすると、多くの場合、不正メモリアクセスで落ちます。

もともと何も格納していないargs[3]なので指定領域が存在していないのでエラーを起こしているというイメージであっていますか?

その通りですね。

そしてその時だと関数内でargs[3]に文字列を格納したい場合はmallocで動的に領域を確保するのが正しいのでしょうか?

なんとも言えません。mallocで獲得したらfree等で開放する必要が有ります。
他のポインタが指す領域もmallocで獲得されていればfreeで開放する際に問題はでませんが、一部のargs[i]はmallocで獲得され、一部のargs[j]はそうでない場合、mallocで獲得されているのかそうでないのか、記録しておく必要があります。

もし、他のargs[j]の内容が文字列リテラル("文字列"みたいなやつ)へのポインタだった場合で、かつ、設定したい文字列が文字列リテラルだけならば、文字列リテラルを直接代入(コピーではない)すれば開放不要なので手抜きできます。

投稿2017/07/11 15:22

Chironian

総合スコア23272

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

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

tekondo

2017/07/12 09:00

素早いご返事ありがとうございました。参考になりました。wild関数内で新しくポインタ配列宣言してそこにコピーしていくことで対処していこうかなと思います。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問