0

このコードに問題があります。「PrepareEncryption」(例) を実行すると、コードは有効なポインターを返しますが、それを「EncryptBig」に渡すと、有効ではなくなります (乱数を指します)。私の最善の策は、元の構造体が削除されることです。それが問題である場合、どうすればそれを保存できますか?そして、ところでメモリリークがあることを知っています。

struct filecrypt
{
    FILE* bestand;
    FILE* nieuwbstnd;
    unsigned int positie;
    unsigned int size;
    unsigned int huidig;
    float procentum;
};

struct filecrypt *PrepareEncryption(char* locatie)
{
    struct stat file_status;
    struct filecrypt origineel, *mirror;
    int error;
    char* nieuw;

    if (stat(locatie, &file_status) != 0)
        return NULL;

    error = fopen_s(&origineel.bestand, locatie, "rb");
    if (error != 0)
        return NULL;

    error = strlen(locatie)+5;
    nieuw = (char*)malloc(error);
    if (nieuw == NULL)
        return NULL;
    strcpy_s(nieuw, error-3, locatie);
    strcat_s(nieuw, error, ".cpt");

    error = fopen_s(&origineel.nieuwbstnd, nieuw, "wb+");
    if (error != 0)
        return NULL;

    origineel.huidig = 0;
    origineel.positie = 0;
    origineel.procentum = 0.0f;
    origineel.size = file_status.st_size;
    mirror = &origineel;
    return mirror;
}

float EncryptBig(struct filecrypt *handle)
{
    int i, index = 0;
    float calc;
    char buf, *bytes = (char*)malloc(10485760); // 10 MB
    if (bytes == NULL)
    {
        handle = NULL;
        fcloseall();
        return -1.0f;
    }

    for (i = handle->huidig; i < (handle->huidig+10485760); i++)
    {
        if (i > handle->size)
            break;

        fseek(handle->bestand, i, SEEK_SET);
        fread_s(&buf, 1, 1, 1, handle->bestand);

        __asm
        {
            mov         eax, dword ptr [bytes]  
            add         eax, dword ptr [index]  
            mov         cl, byte ptr [buf]
            xor         cl, 18
            xor         cl, 75
            not         cl
            mov         byte ptr [eax], cl 
            mov         eax, dword ptr [index]  
            add         eax, 1  
            mov         dword ptr [index], eax
        }
    }

    fwrite(bytes, 1, i, handle->nieuwbstnd);
    fseek(handle->nieuwbstnd, i, SEEK_SET);

    handle->huidig += i;
    calc = (float)handle->huidig;
    calc /= (float)handle->size;
    calc *= 100.0f;

    if (calc == 100.0)
    {
        // GEHEUGEN LEK!
        // MOET NOG BIJGEWERKT WORDEN!
        fcloseall();
        handle = NULL;
    }
    return calc;
}

void example(char* path)
{
    float progress;
    struct filecrypt* handle;

    handle = PrepareEncryption(path);
    do
    {
        progress = EncryptBig(handle);
        printf_s("%f", progress);
    }
    while (handle != NULL);
}
4

3 に答える 3

4

これは、ローカル変数へのポインターを返すためです。

ローカル変数はスタックに格納され、関数が戻ると、スタックのその領域が他の関数によって再利用され、現在使用されていないメモリまたは他の何かによって占有されているメモリを指すポインターが残ります。これは未定義の動作であり、動作することもあれば、「ガベージ」データが表示されることもあり、クラッシュすることもあります。

于 2012-11-23T15:32:12.143 に答える
0

PrepareEncryptionstruct filecrypt origineelでは、スタック (ローカル オブジェクト) に割り当てられている へのポインターを返しています。これが問題です。関数が戻った (実行を終了した) 直後に、占有されていたメモリはorigineel無効になります。malloc を呼び出して、ヒープに割り当てる必要があります。

于 2012-11-23T15:32:46.070 に答える
0

あなたがやる:

mirror = &origineel;
return mirror;

origineelローカル変数です。上記は次と同等です。

return &origineel;

...関数の最後でスコープ外になるローカル変数へのポインターを返しています。時々有効なポインターを返すように見えるという事実は、単なる偶然です。

を使用するmallocか、さらに良いことに、関数への引数としてターゲットの場所へのポインター アドレスを渡し、それを返さないでください。

int *PrepareEncryption(struct filecrypt *origineel, char* locatie);

struct filecrypt myStruct;
PrepareEncryption(&myStruct, "abc");
于 2012-11-23T15:33:59.913 に答える