我正在尝试使用方法
testing_malloc()
释放在 testing_free()
中分配的所有内存。我正在使用 Google 测试项目来测试我的代码和这个答案中提到的 MemoryLeakDetector。
但是,当我尝试释放 private_data
时,我收到以下堆损坏错误。
检测到堆损坏:在 0x00000263D9A97F40 处的普通块(#835)之后。 CRT 检测到应用程序在堆缓冲区结束后写入内存。
测试.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
测试.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;
}
测试.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_;
};
我尝试了
testing_free
中的两个注释语句,但其中任何一个都给了我堆损坏消息。如果我对它们进行评论,MemoryLeakDetector 会正确报告我正在泄漏内存。我删除了 MemoryLeakDetector 并取消注释了 testing_free
中的任一注释语句,但仍然收到错误。
我确实注意到我没有收到使用控制台应用程序测试testing_malloc和testing_free的异常
控制台.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;
}
所以这让我相信这是使用 Google Test 的问题。 如何正确释放以下语句分配的内存而不破坏我的 GoogleTest 项目?
internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));
您致电
free
。问题不在于你如何称呼 free
,而在于你如何称呼 malloc
。
在一种类型的计算机上
TestStruct
是 8 个字节,InternalTestStruct
是 24 个字节,所以:
internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));
这一行分配了 8 个字节,但随后您设置了所有 24 个字节,就好像您有足够的空间来容纳
InternalTestStruct
,但实际上您没有。额外的 16 个字节不是你的。因为您在编译器中使用某种调试模式(可能是默认情况下),所以 free
检查您分配的内容之前和之后的字节,以确保您没有触及它们,以帮助捕获错误。你确实触摸了它们,所以它捕获了错误。
解决方案:分配正确的字节数(
sizeof(InternalTestStruct)
)