1. ホーム
  2. c++

[解決済み] HEAPエラー RtlValidateHeapに指定したアドレスが無効です。

2022-02-17 12:16:42

質問

メモリで困っています。構造体をこのように使っています。

Package.hファイル

#pragma once
#include <cstdlib>

struct Package {
    char *data;
    long long int *packageNumber;
    long long int *allPackages;

    Package(const int sizeOfData);
    ~Package();
};

パッケージ.cpp

#include "Package.h"

Package::Package(const int sizeOfData) {
    void *ptr = malloc(2 * sizeof(long long int) + sizeOfData * sizeof(char));
    packageNumber = (long long int*) ptr;
    allPackages = (long long int*) ((long long int*)ptr + sizeof(long long int));
    data = (char*)((char*)ptr + 2 * sizeof(long long int));
}

Package::~Package() {
    free(data);
    free(packageNumber);
    free(allPackages);
}

そしてメソッドでは

for (int j = 0; j < this->bufforSize || i * bufforSize + j < allPackages; j++) {
            Package package(this->packageSize);
            this->file->read(package.data, this->packageSize);
            *package.allPackages = allPackages;
            *package.packageNumber = i * this->bufforSize + j;
            this->dataPacked->push_back(package);
        }

の後では、エラーが発生します。 "HEAP[zad2.exe]: Invalid address specified to RtlValidateHeap( 00000056FEFE0000, 00000056FEFF3B20 )" 何が間違っているのか全く分かりません。マイケルさん、助けてください。

EDIT: ループの最初のイテレートで動作するようになりました。デストラクタをこれに変更したのが救いです。

Package::~Package() {
    free(packageNumber);
}

しかし、ループの2回目の繰り返しで、同じ構造体オブジェクトに対してデストラクタが2回実行されるようになりました。

どうすればいいですか?

をお読みください。 説明 free :

ptr の値が std::malloc(), std::calloc(), std::realloc() によって先に返された値と等しくない場合、動作は未定義となります。

それから、あなたのコードを見て、私が加えたコメントに注意してください。

void *ptr = malloc(2 * sizeof(long long int) + sizeOfData * sizeof(char));
packageNumber = (long long int*) ptr; // you got this from malloc
allPackages = (long long int*) ((long long int*)ptr + sizeof(long long int)); // the value of this pointer is not equal to anything returned by malloc
data = (char*)((char*)ptr + 2 * sizeof(long long int)); // the value of this pointer is not equal to anything returned by malloc either

そして最後にデストラクタで。

free(data); // was not allocated with malloc -> undefined behaviour
free(packageNumber); // was allocated with malloc -> OK
free(allPackages); // was not allocated with malloc -> undefined behaviour

から取得していないポインタを削除しようとした場合。 malloc . この結果、未定義の動作が発生します。エラーは未定義の動作によるものです。このように free(packageNumber) で割り当てられたメモリブロック全体を解放します。 malloc . これには dataallPackages .

簡単な経験則があります。コール free を1回呼び出すごとに、ちょうど1回 malloc / calloc . 以下も同様です。 delete + newdelete[] + new[] .