重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

教えてGoo運営側に内容チェックされているため再度内容を変更し質問させていただきます。
http://oshiete.goo.ne.jp/qa/8080757.html
(ダンプを書いたのがまずかったかもしれないので、ここでは削除します。)

<プログラムで実行したいこと>
・簡単なリストを作成
・リストを構成する構造体のメンバはchar*などのメンバがあり、
 特に、char*にstrdupにて文字列をコピーする。(正確には文字列のポインタをコピーする。)
・作ったリストをプリントする。
・領域を確保する。

下記のソースで動くと思ったのですが、領域のfreeでうまくいきません。
どうもない領域をfreeしているようなのです。それがなぜかわかりません。
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000020eb030 ***
どうしたら、解決するのか、どこが悪いのかご指摘いただけないでしょうか。
以下、私が書いたソースになります。

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

struct word {
struct word *next;
char *st;
int *line_no;
int line_cnt;
};

struct word *head;

void Add_List(char *buf,int no){

struct word* node = malloc(sizeof(struct word*));
struct word* crnt;

/*nodeの準備*/
node->next = NULL;
//node->st = strdup(buf);
node->st = malloc(sizeof(char)*10);
strcpy(node->st,buf);

node->line_no = malloc(sizeof(int*));
node->line_no[0] = 1;
node->line_cnt= 1;

if(head == NULL) {
head = node;
} else {
crnt = head;

while( crnt->next != NULL) {
crnt = crnt->next;
}

crnt->next = node;
}

}

void printlist(){

struct word *crnt = head;

while( crnt != NULL ) {
printf("%s\n",crnt->st);
crnt = crnt->next;
}

}

int main(){

head = NULL;

char buf1[] = {'A','B','C','D','E','\0'};
char buf2[] = {'F','G','H','I','J','\0'};
char buf3[] = {'K','L','M','N','O','\0'};


Add_List(buf1,1);
Add_List(buf2,1);
Add_List(buf3,1);


printlist();

/*この部分がうまくいかない*/
printf("%s\n",head->st);
printf("%x \n",head->st);
free(head->st);
/*********************/

}

A 回答 (2件)

既に回答あるように、確保したサイズが正しくないのでバッファオーバーランしてぶっ壊してます。


ぶっ壊した後で正常動作を期待しても、無理でしょうね。

>struct word* node = malloc(sizeof(struct word*));

「ポインタ1つが入る領域」を確保しています。
ので、struct wordとして有効なメモリは
struct word *next;
のメンバの分しかありません。
struct wordとして使える分のメモリは確保されていません。

>node->next = NULL;

ここでは正常に確保できた領域に書き込んでます。

>node->st = malloc(sizeof(char)*10);

malloc()は実行できますが戻り値を書き込んだ先はバッファオーバーランした領域になります。
以降は盛大にぶち壊しながら進みます。
free()の段階になって、ぶち壊された領域に従って解放しようとするも、そこはヒープでなかったりと不正な場所を指していますので、管理領域を書き換えようとしてOSに待ったを掛けられているのでしょう。
    • good
    • 0

とりあえず、以下の2つはおかしいですよ。



>struct word* node = malloc(sizeof(struct word*));

>node->line_no = malloc(sizeof(int*));
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!