【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.18521

メモリの解放に伴う不具合
投稿者---ふい(2004/12/06 10:32:02)


ええと、前回ファイルの取り扱いやmallocで騒いでた者です。初心者のうちにおもっきしこの掲示板利用させていただきます!

本題:
とりあえず一通りは出来てるのですがメモリの解放しようとするとエラーが出ます。(解放しなければ「表面上」は正常動作)⇒「DAMAGE:After normal block (#64) at(メモリのアドレス)」
調べたところmalloc後、またはWhileブロック内でのrealloc後もWhileブロック後もメモリのアドレス変わってません。(なので他関数は不必要と勝手に判断しました。所望された場合は随時載せていこうかと思います。長い、というのもあるので。(350行程度ですが))
とりあえずそのうち一通りのアドバイスを仰ぐために全プログラム丸投げするつもりですが今回は必要最低限なmain部のみでアドバイスよろしくお願いします。


補足:
プログラムの流れとしてはファイル内の文字列置換をリストに従って行う、というものです。
元ファイル・置換用Listファイルの中身をメモリに展開⇒メモリに展開したListファイルから1行を読み込んで置換前後文字列に分解し、置換対象ファイルの中から置換対象文字列検索⇒置換⇒result.txtファイルに書き込む、という流れになってます。


あとプログラムには直接関係ないのですが、完成したらここに全部ぺたっとはっつけて「改善の余地あったらおしえてー!」って感じの書き込みってしてもいいんでしょうか?(だめならあっさり引き下がります(笑))
「普通ならこんなやり方しない」とか「そうやると非効率だ」とかいうコメントが欲しいのです・・・。
では、長くなりましたがヨロシクオネガイシマス!

int main()
{
    //元ファイルのサイズ
    int oriSize;
    //リストファイルの1行保存
    char listChar[MAX_LINE];
    //元ファイルの内容 staticつけても変化無し(Whileブロック内で変化した場合のアドレス値保持のためstatic)
    static char *content;
    //リストファイル内容の処理用。
    int count=0;

    //file name格納
    char oriFName[FILE_NAME];
    char listFName[FILE_NAME];

    inFName(oriFName,"元ファイル");
    inFName(listFName,"リストファイル");
    oriSize = getFileSize(oriFName);

    content = (char *)calloc(oriSize,sizeof(char));

    if(content==NULL)
    {
        error("領域確保失敗");
    }
    readAllInFile(oriFName,content,oriSize);
    int lineNo=1;
    char *tempCont;

    while(getaLine(listChar,listFName,lineNo)== NEXT)
    {
        char *before;
        char *after;
        int amount;
        int gap;
        int times;

        tempCont = (char *)calloc(oriSize,sizeof(char *));

        before = strtok(listChar,SEPARATE);
        after = strtok(NULL,SEPARATE);

        //1回の置換に生じる置換前・置換後のサイズ変化
        gap=checkAndCal(listChar,before,after,lineNo);
        //何度置換が生じるかのチェック
        times = calTimes(before,content);
        //その結果、生じるファイルサイズ差
        amount = times * gap;
        //置換後のファイルのサイズ
        amount += strlen(content);

        strcpy(tempCont,content);
        content = (char *)realloc(content,amount);
        changeW(before,after,tempCont,gap);
        strcpy(content,tempCont);
        ++lineNo;
    }

    free(tempCont);

    writeAllInFile("result.txt",content,strlen(content));

    //解放するとエラー。Whileブロック内でも同様      free(content);


    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:メモリの解放に伴う不具合 18522 επιστημη 2004/12/06 11:20:05
<子記事> Re:メモリの解放に伴う不具合 18524 あるた 2004/12/06 11:41:44
<子記事> Re:メモリの解放に伴う不具合 18526 ふい 2004/12/06 12:55:51
<子記事> Re:メモリの解放に伴う不具合 18527 ふい 2004/12/06 17:28:28


No.18522

Re:メモリの解放に伴う不具合
投稿者---επιστημη(2004/12/06 11:20:05)


文字列を格納するときは末尾の'\0'を考慮して strlen(文字列)+1 確保しますけど、ここらへん抜かりないですか?



この投稿にコメントする

削除パスワード

No.18523

Re:メモリの解放に伴う不具合
投稿者---ふい(2004/12/06 11:38:50)


>文字列を格納するときは末尾の'\0'を考慮して strlen(文字列)+1 確保しますけど、ここらへん抜かりないですか?

えぇと、とりあえず+1とかしてみましたが特に何も変わりませんでした・・・。
#amount += strlen(content);
#の部分ですよね?
どちらにせよ抜かりまくりでした。orz


この投稿にコメントする

削除パスワード

No.18524

Re:メモリの解放に伴う不具合
投稿者---あるた(2004/12/06 11:41:44)


> free(tempCont);
ループ内で確保してるのに、解放はループ外はまずいと思われ


この投稿にコメントする

削除パスワード

No.18525

Re:メモリの解放に伴う不具合
投稿者---ふい(2004/12/06 11:53:13)


宣言・解放ともにブロック内に入れておきました。<tempCont
前までfree(content);ではなくこちらでエラーが出てると思って外に出したままでした。
ありがとうございます!


この投稿にコメントする

削除パスワード

No.18526

Re:メモリの解放に伴う不具合
投稿者---ふい(2004/12/06 12:55:51)


。。。どうしてtempContの方は解放できるのにContentの方が出来ないのか不思議でなりません。
Whileブロック内でreallocしたためにアドレスが変わった、としてもstaticで解決されるわけですよね?

ね?(不安)

ポインタ「Content」を渡してるのもreadInFile関数のみなんですが下に晒しますがこんな感じです。
・・・何がいけないんでしょう・・・

/**************************************************************************
ファイル読み込み用関数

渡された文字配列にファイルの中身を詰める。
arg:ファイル名、ファイルから読み取った文字列の格納用ポインタ、ファイルサイズ
ret:int_freadと同じ返し値
***************************************************************************/
int readAllInFile(char *fileName,char *input,int fileSize)
{
    int size;
    FILE *filePtr;
    if((filePtr = fopen(fileName,"r"))==NULL)
    {
        printf("ファイル\"%s\"のオープンに失敗しました。\n",fileName);
        exit(1);//ここは後で直す予定です。
    }
    else
    {
        size = fread(input,1,fileSize,filePtr);
        fclose(filePtr);

        return size;
    }
}




この投稿にコメントする

削除パスワード

No.18527

Re:メモリの解放に伴う不具合
投稿者---ふい(2004/12/06 17:28:28)


恐らく解決しました。
毎回Freeのコメントアウト外す度にエラーだったのでずっと解放の問題だと思っていたのですがどうやらどこかで数字が食い違ってメモリの情報破壊してたっぽいです。
置換の度に先に置換後の必要領域の調査をし、その分領域確保、ってやってたつもりだったんですがその辺がうまくいってなかったようです。
バイナリで読むと置換の度に改行がはいるしtxtで読むたびにサイズがばらばら。ってどっちつかえばいんだー!
もう全然前回と変わらないような質問してる気がします・・・。うぅん、すみませんでしたお手数かけて。

とりあえずお答えくださったお二方ありがとうございました、恐らく次はちゃんと仕上げて丸投げしにきますのでまたそのときにもアドバイスいただけると幸いです。(丸投げって言うか全体通してのコメントをいただきに・・・)

とにもかくにも、どもでしたー!


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧