Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HEAP error Invalid address specified to RtlValidateHeap

I have troubles with memory. I'm using struct this way:

Package.h file

#pragma once
#include <cstdlib>

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

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

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);
}

And in method:

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);
        }

after end of brackets it throws error: "HEAP[zad2.exe]: Invalid address specified to RtlValidateHeap( 00000056FEFE0000, 00000056FEFF3B20 )" I have no idea what I'm doing wrong. Please help, Michael.

EDIT: Now it is working for first iterate of loop. Helps that I changed destructor to this:

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

But now destructor is executed two time on same struct object in 2'nd iterate of loop.

like image 833
PianistaMichal Avatar asked Nov 09 '15 16:11

PianistaMichal


1 Answers

Read the description of free:

The behavior is undefined if the value of ptr does not equal a value returned earlier by std::malloc(), std::calloc(), or std::realloc().

Then take a look at your code, pay attention to the comments I added.

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

And finally in the destructor:

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

You try to delete pointers that you didn't get from malloc. This results in undefined behaviour. The error is due to the undefined behaviour. Do realize that free(packageNumber) frees the entire block of memory allocated with malloc. That includes the memory pointed by data and allPackages.

There is an easy rule of thumb: Call free exactly once per every call to malloc/calloc. Same applies to delete+new and delete[]+new[].

like image 107
eerorika Avatar answered Oct 24 '22 00:10

eerorika