構造体へのポインタを動的確保しようとmalloc関数を使用すると
segmentation faultが起きます。
typedef struct cell{
char *word;
int count;
struct cell *next;
}node_t;
という構造体で
node_t *ptr=(node_t*)malloc(sizeof(node_t)*num);
という風に動的確保しようとするとsegmentation faultが起きました。
gdbを使って調べると
Starting program: /home/programII/week05/a.out file1 file2
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
というメッセージが返ってきます。
これはライブラリとのリンクが正しく行われていないということでしょうか?
しかし、ポインタの動的確保以外でmalloc関数を使用すると
正常に動作するのでライブラリ自体が無いわけではないようです。
ptr[2]といった風にポインタを参照したいのですが上手くいきません。
よろしくお願いします。
No.7
- 回答日時:
直接のエラーの原因は
for (i = 1, p = list; i <= num; i++, p = p->next) {
ptr[i] = *p;
}
ここでしょう。
配列をnum個しか確保していないのに、num番目を使ってはいけません。
C言語での配列は、0~num-1を使用します。
また、
free(p);
と解放していることも変ですね。
No.5
- 回答日時:
>Program received signal SIGSEGV, Segmentation fault.
>0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
>というのは、main関数に入る前に
>segmentation faultを起こしているように思えるのですが
>どうなのでしょうか。
自分の書いたコードに非はないと思い込みたい気持ちはわからなくないですが、nodePrependの使い方がおかしいです。
nodePrependを呼び出す前にやるべき事を忘れていませんか。
No.3
- 回答日時:
>このmallocの後にfree(ptr)だけを書いてもsegmentation faultが起きます。
それだけだと起きそうにないと思われるんですけどねぇ。
念のため、
sizeof(node_t) はいくつになります?
num に入っている値はいくつです?
ポインタ2つにint型1つですから、たいしたサイズにはならないハズですけど。
# 64Bit環境っぽい…けど、特にオプション指定しなかった場合にint型が何ビットになったかなぁ…。
取得したポインタに対して何らかの操作を行った…とか、
32Bitと64Bitが混在した…とかでしょうかねぇ……。
周辺のコードを掲示した方がいいかも知れませんね。
# malloc()直後にfree()でも死ぬ…というのが変ですが…。
# numが異常な値でメモリ確保できなかった場合はNULL返却でしょうし。
この回答への補足
返答ありがとうございます。以下、コードです。
-------------------------------------
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct cell{
char *word;
int count;
struct cell *next;
}node_t;
int readword(FILE *fp,char *s);
node_t *alloc_node_t(node_t *ndPtr,char *s);
void nodePrepend(node_t **ndPtrPtr,char *s);
void selection_sort(node_t *ndPtr,int n);
void listprint(node_t *ndPtr);
void heapsort(node_t *ndPtr[],int n);
void downheap(node_t *ndPtr[],int leaf,int root);
void swap(node_t *ndPtr[],int i,int j);
int main(int argc,char *argv[]){
int i,num=0;
FILE *fp;
char buf[32];
node_t *list,*p;
for(i=1;i<argc;i++){
if((fp=fopen(argv[i],"r"))==NULL){
fprintf(stderr,"cannot open %s\n",argv[i]);
return 1;
}
while(readword(fp,buf)!=0){ //文字列の読み取り
nodePrepend(&list,buf); //線形リストへの追加
}
fclose(fp);
}
for(p=list;p!=NULL;p=p->next){
num++; //要素数のカウント
}
selection_sort(list,num); //単純選択法によるソート
listprint(list); //線形リストを表示
printf("----------------------------------------\n");
num++;
node_t *ptr=(node_t*)malloc(sizeof(node_t)*num); //ポインタの配列の動的確保
for(i=1,p=list;i<=num;i++,p=p->next){
ptr[i]=*p;
}
/* heapsort(ptr,num);
for(i=1;i<num+1;i++){
printf("%s %d\n", ptr[i]->word , ptr[i]->count);
}
*/
free(p);
return 0;
}
int readword(FILE *fp,char *s){
int ch,k=0;
while((ch=getc(fp))==' '|| ch=='\t' || ch=='\n'){};
if(ch==EOF) return 0;
s[k]=ch;
k++;
while((ch=getc(fp))!=' ' && ch!='\t' && ch!='\n' && ch!=EOF){
s[k]=ch;
k++;
}
s[k]='\0';
return 1;
}
node_t *alloc_node_t(node_t *ndPtr,char *s){
node_t *p;
p=(node_t *)malloc(sizeof(node_t));
p->word=(char *)malloc(strlen(s)+1);
strcpy(p->word,s);
p->count=1;
p->next=ndPtr;
return p;
}
void nodePrepend(node_t **ndPtrPtr,char *s){
node_t *ndPtr;
for(ndPtr=*ndPtrPtr;ndPtr!=NULL;ndPtr=ndPtr->next){
if(strcmp(ndPtr->word,s)==0){
ndPtr->count++;
return;
}
}
ndPtr=alloc_node_t(*ndPtrPtr,s);
*ndPtrPtr=ndPtr;
}
void selection_sort(node_t *ndPtr,int n){
int i,j,min_count,temp_count;
char *min,*temp_word;
node_t *p,*q,*k;
for(i=0;i<n;i++){
p=ndPtr;
if(i!=0){
for(j=0;j<i;j++){p=p->next;};
}
min=p->word;
min_count=p->count;
k=p;
for(q=p->next;q!=NULL;q=q->next){
if(strcmp(min,q->word)>0){
min=q->word;
min_count=q->count;
k=q;
}
}
temp_word=p->word;
temp_count=p->count;
p->word=min;
p->count=min_count;
k->word=temp_word;
k->count=temp_count;
}
}
void listprint(node_t *ndPtr){
int i;
while(ndPtr!=NULL){
for(i=0;i<ndPtr->count;i++){
printf("%s\n",ndPtr->word);
}
ndPtr=ndPtr->next;
}
}
----------------------------------------
与えられた課題が
「ファイルから文字列を読み取り、単純選択法により文字が小さい順にソートする。
その後、ヒープソートにより出現回数の少ない順にソートする」
というものです。
読み取った文字列を線形リストに保存し、単純選択法によるソートまではできたのですが
ヒープソートをするためにポインタを配列に動的確保しようとしたところで
segmentation faultが起きました。
動的確保ができなかったのでヒープソートをする部分は省略していますが
これでもsegmentation faultが起きます。
sizeof(node_t)は12、numは11のようです。
配列を動的確保せずにヒープソートした方がいいのでしょうか…
また
Starting program: /home/programII/week05/a.out file1 file2
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
というのは、main関数に入る前に
segmentation faultを起こしているように思えるのですが
どうなのでしょうか。
よろしければ引き続きお願い致します。
No.2
- 回答日時:
>動的確保以前のプログラムは正しく動作するのですが……
そういう場合は「正しく動作しているように見えてるだけ」という事もあります。
うちの環境はlinuxではなくFreeBSDですけど
% cat node.c
#include <stdio.h>
#include <stdlib.h>
typedef struct cell {
char *word;
int count;
struct cell *next;
} node_t;
int
main(int argc, char **argv)
{
int num = 10;
node_t *ptr = malloc(sizeof(node_t) * num);
printf("%p\n", ptr);
free(ptr);
return 0;
}
% cc -o node node.c
% ./node
0x801006100
%
何の問題もなく動きますけど。
No.1
- 回答日時:
>node_t *ptr=(node_t*)malloc(sizeof(node_t)*num);
>という風に動的確保しようとするとsegmentation faultが起きました。
本当にそのmallocで起きてるsegmentation faultですか。
その後に書いてる何らかの処理で起きてるんじゃないですか?
この回答への補足
このmallocの後にfree(ptr)だけを書いてもsegmentation faultが起きます。
また、このmallocとfreeをコメントアウトすると
動的確保以前のプログラムは正しく動作するのですが……
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Android(アンドロイド) Team microSDXCカード 256GB この製品は有名で性能は良いものでしょうか 5 2022/09/24 23:25
- C言語・C++・C# C言語で構造体の参照渡しができません 2 2022/12/18 21:22
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c言語のポインタへの文字列入力...
-
MSDNがgethostbynameではなくge...
-
allocってなんですか?
-
ビットをローテートするプログ...
-
ヒープメモリの解放について
-
指定したメモリアドレスの値の...
-
malloc呼び出し時のセグメンテ...
-
プログラムが途中で強制終了し...
-
bool と BOOL の違い(構造体)
-
callocの処理速度
-
入れ子になった構造体について
-
【VC++6.0(MFC)】メモリの静的...
-
16進ダンプのプログラム
-
DLLのマルチスレッドの動作につ...
-
mallocについて
-
newしないオブジェクトについて
-
C言語に関する質問
-
DLLで同じメモリ領域を参照する...
-
malloc()関数内でセングメント...
-
画像を読み込む配列の確保。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
mallocについて
-
c言語のポインタへの文字列入力...
-
allocってなんですか?
-
newしないオブジェクトについて
-
ヒープメモリの解放について
-
C++で、メンバもヒープに確保さ...
-
MSDNがgethostbynameではなくge...
-
プログラムが途中で強制終了し...
-
配列の添え字の最大数とは?
-
Accessで、メモリを開放するタ...
-
ヒープ領域の限界値設定
-
malloc呼び出し時のセグメンテ...
-
スタック破壊の上手な見つけ方...
-
C言語 mallocとfreeについて
-
指定したメモリアドレスの値の...
-
stringの最大サイズ
-
16進ダンプのプログラム
-
64ビットと32ビットの違い
-
入れ子になった構造体について
-
free関数で動作が止まる
おすすめ情報