I'm trying to free all the memory allocated in testing_malloc() with the method testing_free(). I am using a Google Test project to test my code and the MemoryLeakDetector mentioned in this answer.
However, when I try to free the private_data I get the following heap corruption error.
HEAP CORRUPTION DETECTED: after Normal block (#835) at 0x00000263D9A97F40. CRT detected that the application wrote to memory after end of heap buffer.
testing.h:
#ifndef testing_h
#define testing_h
typedef struct TestStruct {
void* private_data;
} TestStruct;
void test_method();
int testing_malloc(int input, int is_negative, int length, TestStruct* out);
int testing_free(TestStruct* to_free);
#endif
testing.c:
#include "testing.h"
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
struct TestStruct {
void* private_data;
};
typedef struct InternalTestStruct {
int* value_array;
int* length;
int* is_negative;
} InternalTestStruct;
int testing_malloc(int input, int is_negative, int length, TestStruct* out)
{
InternalTestStruct* internaltesting;
if (input < 0 || input > 9)
{
return 1;
}
internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));
if (!internaltesting)
{
return 2;
}
internaltesting->is_negative = (int*)malloc(sizeof(int));
if (!internaltesting->is_negative)
{
free(internaltesting);
return 2;
}
*internaltesting->is_negative = is_negative;
internaltesting->length = (int*)malloc(sizeof(int));
if (!internaltesting->length)
{
free(internaltesting->is_negative);
free(internaltesting);
return 2;
}
*internaltesting->length = length;
internaltesting->value_array = (int*)malloc(sizeof(int) * length);
if (!(internaltesting->value_array))
{
free(internaltesting->length);
free(internaltesting->is_negative);
free(internaltesting);
return 2;
}
memset(internaltesting->value_array, 0, sizeof(int) * length);
internaltesting->value_array[0] = input;
out->private_data = internaltesting;
return 0;
}
int testing_free(TestStruct* to_free)
{
InternalTestStruct* internaltesting = (InternalTestStruct*)to_free->private_data;
free(internaltesting->value_array);
free(internaltesting->length);
free(internaltesting->is_negative);
/*free(internaltesting);*/
/*free(to_free->private_data);*/
return 0;
}
test.cpp
#include "pch.h"
#include "../Testing/testing.h"
#include "../Testing/testing.c"
namespace testns
{
TEST(construct_tests, construct_zero_does_not_leak) {
MemoryLeakDetector leakDetector;
int length = 1;
int is_negative = 0;
int expected_value = 0;
TestStruct* zero = (TestStruct*)malloc(sizeof(void*));
if (!zero)
{
FAIL();
}
int result = testing_malloc(expected_value, is_negative, length, zero);
if (!zero->private_data || result != 0)
{
free(zero);
FAIL();
}
testing_free(zero);
free(zero);
}
}
pch.h
//
// pch.h
//
#pragma once
#include "gtest/gtest.h"
#include <crtdbg.h>
class MemoryLeakDetector {
public:
MemoryLeakDetector() {
_CrtMemCheckpoint(&memState_);
}
~MemoryLeakDetector() {
_CrtMemState stateNow, stateDiff;
_CrtMemCheckpoint(&stateNow);
int diffResult = _CrtMemDifference(&stateDiff, &memState_, &stateNow);
if (diffResult)
reportFailure(stateDiff.lSizes[1]);
}
private:
void reportFailure(unsigned int unfreedBytes) {
FAIL() << "Memory leak of " << unfreedBytes << " byte(s) detected.";
}
_CrtMemState memState_;
};
I tried both of the commented statements in testing_free but either one gives me the heap corruption message. If I leave them commented, the MemoryLeakDetector correctly reports that I'm leaking memory. I removed the MemoryLeakDetector and uncommented either of the commented statements in testing_free and still got the error.
I did note that I did not receive the exception using a console app to test testing_malloc and testing_free
console.c
#include "testing.h"
#include <stdio.h>
#include <malloc.h>
int main(int charc, char** charv)
{
int length = 1;
int is_negative = 0;
int expected_value = 0;
int result;
TestStruct* zero = (TestStruct*)malloc(sizeof(void*));
if (!zero)
{
return 1;
}
result = testing_malloc(expected_value, is_negative, length, zero);
if (!zero->private_data || result != 0)
{
free(zero);
return 1;
}
testing_free(zero);
free(zero);
return 0;
}
So that leads me to believe that it is an issue with using Google Test. How do I properly free the memory allocated by the following statement without breaking my GoogleTest project?
internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));
TestStruct* zero = (TestStruct*)malloc(sizeof(TestStruct));Alternatively, you could make itTestStruct zeroand use &zero later as the parameter to the function call as the lifetime is ok in this situation.internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));has the same sort of error. It needs to beinternaltesting = (InternalTestStruct*)malloc(sizeof(InternalTestStruct));. You need to allocate the amount of memory for the thing you are allocating.