1

簡単なプログラムで C の malloc/free 関数を使用しようとしています。

void* alloc_array( const int size )
{
    void* p;

    p = malloc( size );
    if( p )
    {
        //memset(p, 0, size);
        return( p );
    }
    else
        return NULL;
}

void free_array( void* p )
{
    if( p )
    {
        free( p );
        p = NULL;
    }       
}

void** alloc_array_ptr( const int nPointers )
{
    void** p;   
    unsigned int size = AMOUNT_TO_ALLOC(nPointers, void*);

    p = malloc( size );
    if( p )
    {
        return( p );
    }
    else
        return( NULL );
}

void free_array_ptr( void** p, const int nPointers )
{
    unsigned int i;

    if( p )
    {
        for( i = 0; i < nPointers; i++ )
            if( p[i] )
            {
                free( p[i] );
                p[i] = NULL;
            }

        free(p);
        p = NULL;
    }
}
int main(int argc, char* agv[]) {
    // builds the string with the location of the ini file
    int inifile_size = 0;
    char* inifile;
    // gets the buffer size nedeed for the buffer
    inifile_size = GetCurrentDirectory(0, NULL);
    // allocates memory for the buffer
    inifile = (char*) alloc_array( AMOUNT_TO_ALLOC(inifile_size, char) );
    // fills the buffer with the current directory
    if( GetCurrentDirectory( inifile_size, inifile ) == 0 )
    {
        printf("GetCurrentDirectory failed! (ErrorCode: %u)\n", GetLastError());
        return( !MY_ERROR_OK );
    }
    strcat(inifile, "\\");
    strcat(inifile, "test.ini");    
    printf("INI File: %s\n", inifile);

    char** sessions;
    int nSessions = 0;
    int i;

    nSessions = getNumberOfSubkeys(str);
    printf("\nOK (%d sessions found)\n", nSessions);

    // allocating memory for the sessions array of char*
    sessions = (char**) alloc_array_ptr( nSessions );

    if( sessions == NULL )
    {
        printf("ERROR_IN_MEM_ALLOC (SESSIONS)\n");      
        return( MY_ERROR_MEM_ALLOC );
    }
    else
        printf("sessions: 0x%p\n", sessions);

    // allocating memory for each one of the char* in sessions
    for( i = 0; i < nSessions; i++ )
    {
        sessions[i] = (char*) alloc_array( AMOUNT_TO_ALLOC(MAX_KEY_LENGTH, char) );

        printf("sessions[%d]: 0x%p\n", i, sessions[i]);

        if( sessions[i] == NULL )
        {
            printf("ERROR_IN_MEM_ALLOC (SESSIONS[%d])\n", i);
            return( MY_ERROR_MEM_ALLOC );                   
        }
    }

    printf("\nSessions found:\n");

    if( readSubkeys( str, sessions ) == MY_ERROR_OK )
    {
        for( i = 0; i < nSessions; i++ )
        {
            printf("\t%s: ", sessions[i]);

            if( convert2ini(inifile, sessions[i]) == MY_ERROR_OK )
                printf("OK\n");
            else
            {
                printf("ERROR\n");
                return( !MY_ERROR_OK );
            }           
        }
    }
    else
    {
        printf("ERROR\n");
        return( MY_ERROR_OPEN_REGISTRY );   
    }

    // free the inifile array
    free_array(inifile);

    // free the array of char*
    free_array_ptr( (void**)sessions, nSessions );      

    // returns to OS
    return( MY_ERROR_OK ); 
}

これは、Windows レジストリ内の一部のプログラム設定を ini ファイル (Windows7、64 ビット、4Gb RAM) に変換するための小さなツールです。

readSubkeys は、事前に割り当てられた char* のセッション配列に、str のレジストリ キーから取得したセッションの名前を入力します。

getNumberOfSubkeys は、指定されたレジストリ内のサブキーの数を返します

コードの残りの部分は、これには関係ありません。問題は、for ループ内で char* のそれぞれにメモリを割り当てているときに、malloc が失敗することです。CodeLite を使用してこのプログラムを作成していますが、奇妙なことに、コードを段階的にデバッグしているときに malloc が失敗することはありません。

このプログラムの実行イメージはこちらです。 ランニング

誰かアドバイスをお願いできますか?

4

3 に答える 3

2

奇妙なことに、コードを段階的にデバッグしているときに malloc が失敗することはありません。

このステートメントは、コードのどこかにメモリ割り当てエラーがあり、このブロック (たとえば、malloc() 呼び出しまたはアサーション) が失敗したことを意味している可能性があります。コードを追加せずにこれを完全にデバッグするには、十分な情報がありません。

于 2012-08-22T18:36:40.687 に答える
1

申し訳ありませんが、これを回答として投稿する必要があります。コメントを投稿する権限がまだありません。最初の malloc ステートメントでは、malloc の戻り値をポインタ ツー ポインタに型キャストしています。したがって、for ループでは、sessions[0] と言うと、最初の場所 0x00701760 (最初の malloc の後) のアドレスが含まれます。for ループをセッション [1] にインクリメントします。これは技術的に不可能です。セッションには次の値がないため。実際には、sessions[0] に含まれる値をインクリメントする必要があります。*sessions++ のようなものかもしれません。私が言おうとしているのは、0x00701760 を 0x00701762 にインクリメントし、これに対して malloc を実行する必要があるということです。したがって、0x00701762 には、新しく割り当てられたメモリのアドレスが含まれるようになりました。次は 0x00701764、次に 0x00701766 です。セッションをインクリメントすると、エラーが発生するか、少なくとも無効なメモリにアクセスします。

ありがとうアディティア

于 2012-08-22T19:08:31.707 に答える
0

ヒントをありがとうございました。

問題は、プログラムの早い段階でメモリを正しく割り当てていなかったことです。奇妙なことに、ソフトウェアのこの部分は機能しましたが、その後のメモリ割り当ては失敗しました。私が解決したことは、区切り記号とファイル名を追加するためのいくつかの strcat 呼び出しを含め、malloc しなければならなかったメモリの正しいサイズを計算したことです。その後、ソフトウェアは問題なく動作しました。問題のある部分を書き直してこんな感じになりました。

    // builds the string with the current directory

    // gets the size nedeed for the buffer
    current_path_size = GetCurrentDirectory(0, NULL);

    // allocates memory for the buffer
    current_path = (char*) alloc_array( AMOUNT_TO_ALLOC(current_path_size, char) );

    // gets the current directory
    if( GetCurrentDirectory( current_path_size, current_path ) == 0 )
    {
        printf("GetCurrentDirectory failed! (ErrorCode: %u)\n", GetLastError());
        return( !MY_ERROR_OK );
    }

    // builds the string with the location of the ini file

    // calculates the total amount of memory to alloc
    total_size = current_path_size + strlen(CHAR_SEPARATOR) + strlen(PUTTY_FILENAME) + 1;

    // allocates memory for the full path + filename of the ini file
    ini_file = (char*) alloc_array(AMOUNT_TO_ALLOC(total_size, char));

    // fills the buffer with the path + separator + filename + leading '\0'
    strcat(ini_file, current_path);
    strcat(ini_file, CHAR_SEPARATOR);
    strcat(ini_file, PUTTY_FILENAME);
    ini_file[total_size - 1] = '\0';

応答なしで残された 1 つのことは、デバッガーがコードをクラッシュさせなかった理由です。私はまだこれについてさらに研究を行う必要があります。

于 2012-08-22T20:56:31.743 に答える