char型のポインタの配列
Posted: 2011年5月25日(水) 11:36
それなりに演習を経ても未だにポインタがいまいち理解できず、またしても課題に詰まってしまったので質問させてもらえないでしょうか。
第一引数で与えられた名前のファイルを読み込み、ファイルの先頭から7行までを読み込み、7行を超えた場合は読み込みを打ち切り読み込んだ行を標準出力に出力し、7行に満たない場合はそれまで読み込んだすべての行を標準出力に出力する、というプログラムを組みたいのですが
コンパイルは通るものの、実行するとセグメンテーション違反のエラーが発生してしまいます。デバッガのメッセージを見るに、アドレスと思われる値が入っていることが確認できるのでポインタやメモリ確保といった辺りに問題があることは想定できるのですがその部分の理解が足りず問題点をうまく見つけることができません。このプログラムでは、読み込んだ各行の長さにあわせてmalloc()でメモリ領域を確保することが条件として設けられています。どうかアドバイスをいただけないでしょうか。よろしくお願いします。
(デバッガに通したログ)
(gdb) run fruits_list.txt
Starting program: rep4-2 fruits_list.txt
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006ad in main ()
(gdb)
第一引数で与えられた名前のファイルを読み込み、ファイルの先頭から7行までを読み込み、7行を超えた場合は読み込みを打ち切り読み込んだ行を標準出力に出力し、7行に満たない場合はそれまで読み込んだすべての行を標準出力に出力する、というプログラムを組みたいのですが
コンパイルは通るものの、実行するとセグメンテーション違反のエラーが発生してしまいます。デバッガのメッセージを見るに、アドレスと思われる値が入っていることが確認できるのでポインタやメモリ確保といった辺りに問題があることは想定できるのですがその部分の理解が足りず問題点をうまく見つけることができません。このプログラムでは、読み込んだ各行の長さにあわせてmalloc()でメモリ領域を確保することが条件として設けられています。どうかアドバイスをいただけないでしょうか。よろしくお願いします。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
int main(char *argv[])
{
FILE *fp; /* ストリームポインタ */
int len; /* 文字列の長さを取得*/
char tmp[MAXLEN]; /* 取得文字列の一時置き場 */
int i = 0; /* カウンタ1 */
int ii; /* カウンタ2 */
char *str[7]; /* 文字列取得ポインタを7つ用意 */
fp = fopen(argv[1], "r"); /* 第1引数のファイルを開く */
if(fp == NULL){
printf("Can't open file: %s.\n", argv[1]);
return -1;} /* 開けなかった場合エラーを返して終了 */
while(fgets(tmp,MAXLEN,fp) != NULL || i > 7){ /* ファイルの終わりか7回繰り返すまで */
strlen(tmp); /* 文字列の長さ取得 */
str[i] = (char*)malloc(sizeof(char) * len + 1); /* 文字列の長さ+\0分のメモリ取得 */
if(str[i] == NULL){
printf("malloc error.\n");
return -1;} /* 取得失敗の場合エラーを返して終了*/
strcpy(str[i],tmp); /* 取得した文字列を確保したメモリに移す */
i++;
}
if(i == 7)
printf("%s\n", str[6]); /* 7列をこえて終了した場合最後の行のみ表示 */
else{
for(ii = 1; ii == i; ii++)
printf("%s\n",str[ii]);} /* その前に終了した場合取得した行を表示 */
fclose(fp);
i = 0;
while(i == 7){
free(str[i]);
i++;}
free(str); /* ファイルを閉じてメモリを解放 */
return 0;
}
(gdb) run fruits_list.txt
Starting program: rep4-2 fruits_list.txt
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006ad in main ()
(gdb)