如何释放分配给我的 c 项目中结构的 void* 成员的内存而不破坏我的 GoogleTest 项目?

问题描述 投票:0回答:1

我正在尝试使用方法

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

c++ malloc googletest free
1个回答
0
投票

您致电

free
。问题不在于你如何称呼
free
,而在于你如何称呼
malloc

在一种类型的计算机上

TestStruct
是 8 个字节,
InternalTestStruct
是 24 个字节,所以:

internaltesting = (InternalTestStruct*)malloc(sizeof(TestStruct));

这一行分配了 8 个字节,但随后您设置了所有 24 个字节,就好像您有足够的空间来容纳

InternalTestStruct
,但实际上您没有。额外的 16 个字节不是你的。因为您在编译器中使用某种调试模式(可能是默认情况下),所以
free
检查您分配的内容之前和之后的字节,以确保您没有触及它们,以帮助捕获错误。你确实触摸了它们,所以它捕获了错误。

解决方案:分配正确的字节数(

sizeof(InternalTestStruct)
)

© www.soinside.com 2019 - 2024. All rights reserved.