0

以下のコードブロックがあり、不要な部分をすべて削除し、問題のある部分を残しました。関数ごとに必要な特定の形式(YYYYMMDDHHmm)で時間を取得するという私の目的fetch_time。するためにreturn char array、 を使用しmallocました。ただし、以下のコードを 1 分ほど実行すると、プログラムがクラッシュします。デバッグ ツールでコードの実行時間を監視すると、p1 が指すメモリ位置が増加します。たとえば、最初の反復では 0x72120、2 回目の反復では 0x72150 などです。したがって、メモリの問題が原因で失敗したと思われます。どうすれば問題を解決できますか?

ところで、グローバル char 配列を定義し、サブ関数で時間情報を代入することで問題を解決できると思います。mallocの使い方の間違いとその解決方法を教えていただきたいです。ありがとうございました。

int main(int argc,char *argv[]){
    char timedate2[13];
    char *p1 = malloc(strlen(timedate2)+1);
    if(!p1){exit(1);}

    while(1){
        p1=fetch_time();
    }
}

char *fetch_time() {
    char *p;
    time_t rawtime;
    struct tm * timeinfo;
    char buffer [13];

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
    p = (char *)malloc(sizeof(buffer));
    strcpy(p, buffer);
    return p;
}
4

7 に答える 7

2

コードは一見正しく見えます。1つのキャッチ思考があります。を呼び出すときはmalloc、日付文字列を格納するためのある程度のメモリを要求しています。電話をかけるfetch_timeたびに、新しい文字列を使用して(他の)メモリを要求します。同じメモリを再利用して、最終的にメモリが不足することはありません。これを修正するには、要求したすべてのメモリを解放する必要があります。これにより、システムは最終的にそれを再利用できるようになります。

while(1) {
    p1=fetch_time();
    // do something with p1
    free(p1);
}

また、インデントを修正してください。

将来、同様の問題が見つかった場合は、のようなツールの使用を検討してvalgrindください。これは非常に役立ちます(グーグルで検索してください)。

于 2012-06-19T08:43:35.990 に答える
2
char timedate2[13];
char *p1 = malloc(strlen(timedate2)+1);

timedate2は初期化されていないため、割り当てようとしている量を (確実に) 推測する方法はなく、strlen呼び出しが無効なメモリにアクセスしてセグメンテーション違反が発生する可能性があります。割るつもりだったのか

char *p1 = malloc(sizeof timedate2 + 1);

?

しかし、主な問題は、fetch_time呼び出されるたびに新しく割り当てられたバッファーを返すことであり、それは決してfreed ではありません。

于 2012-06-19T08:40:20.767 に答える
2
char timedate2[13];
/* timedate2 is not initialized, so strlen is unpredictable at best*/
char *p1 = malloc(strlen(timedate2)+1);

p1 を割り当ててから使用することはありませんが、fetch_time() の呼び出しで上書きします。これはメモリ リークです。

fetch_time () は問題ないように見えますが、これをタイトなループ (たとえば while(1)) で実行すると、決して解放されない malloced メモリが返されます [メモリ リーク]。

于 2012-06-19T08:41:48.987 に答える
1

プログラムには大きなメモリリークがあります。
まず、main()でメモリをp1に割り当てます。次に、ステートメントの無限ループが発生します。p1=fetch_time();
関数fetch_time()では、メモリをpに割り当て、バッファをコピーします。このアドレスはmain()に返されます。これで、mainで割り当てたp1のメモリアドレスが失われます。
このループは何度も実行されないため、メモリが最大制限に達する段階に到達します。
FAULT 1:p1に割り当てられたメモリが解放されていません。
FAULT 2:関数fetch_timeは、呼び出しごとにメモリをpに割り当て続け、解放しません。 :初期化されていない文字列FAULT 3を呼び出すmalloc(strlen(timedate2)+1);

于 2012-06-19T08:43:59.750 に答える
1

以下のように関数を変更します

while(1){
   fetch_time(p1, strlen(timedate2) + 1);
  }
}
void fetch_time(char * time_str, int format_len)
    time_t rawtime;
    struct tm * timeinfo;
    char buffer [13];

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
    strncpy(p, buffer, format_len);
}

メモリリークやその他の予期しないエラーを回避するため。

于 2012-06-19T09:02:31.613 に答える
1

割り当てられたメモリを解放するのを忘れていませんか? コードは 13 分間動作し、クラッシュしませんでした。

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

char* fetch_time();

    int main(int argc,char *argv[]){

        char timedate2[13];
        char *p1 = malloc(strlen(timedate2)+1);
        if(!p1){exit(1);}
        free(p1);

        while(1){
               p1=fetch_time();
               free(p1);
        }
    }

    char* fetch_time() {
        char *p;
        time_t rawtime;
        struct tm * timeinfo;
        char buffer [13];

        time ( &rawtime );
        timeinfo = localtime ( &rawtime );
        strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
        p = (char *)malloc(sizeof(buffer));
        strcpy(p, buffer);

        return p;
    }

以下の行にもう 1 つ問題があります。

char timedate2[13];
char *p1 = malloc(strlen(timedate2)+1);

'strlen' 関数は、指定された文字配列で最初の記号 '\0' を検索します。しかし、この場合、配列 'timedate2' の内容は定義されておらず、シンボル '\0' はどこにでもある可能性があります。

于 2012-06-19T10:40:32.690 に答える
0

なぜp1を再割り当てするのですか(すでに割り当てられたメモリを指しています)。

また、無期限に fetch_time() を呼び出すと、ヒープ オーバーフローが発生します。

できることは、p1(ポインター) を引数として fetch_time() に渡し、timeinfo を既に割り当てられているメモリーにコピーすることです。

最後に、freeプログラムによって割り当てられたメモリを思い出してください。

于 2012-06-19T08:41:34.173 に答える