首页 > 解决方案 > 结构和内存管理,C

问题描述

我试图了解一些关于结构和内存管理的事情。我有三个版本的代码,其结果是相同的。它们仅在结构的定义/分配上有所不同。在版本一中,该结构分配有以下代码:resultValue_t *resultVal = malloc(sizeof(resultValue_t));. 在第二版中,结构是在函数内部创建的:resultValue_t resultVal;. 在第三版resultValue_t resultVal;中是全局创建的。我想问一下这三个定义实际上有何不同?哪一个给出了哪些可能性?哪个更受赞赏?我知道如果通过指针访问结构,则->应该使用运算符等。但是在这里我很好奇这些定义之间的区别和可能性。

//version_1

typedef struct
{
    int valOne;
    int valTwo;
}resultValue_t;

void twoSum(int *array, int sum)
{
    int baseVal, tempSum;
    int arrLen = sizeof(array);
  
    resultValue_t *resultVal = malloc(sizeof(resultValue_t));
    
    //...
    if (tempSum == sum)
    {
        resultVal->valOne = array[index];
        resultVal->valTwo = array[nIndex];
        printf("%d + %d\n", resultVal->valOne, resultVal->valTwo);
    }
    //...

    free(resultVal);
}

//version_2

typedef struct
{
    int valOne;
    int valTwo;
}resultValue_t;

void twoSum2(int *array, int sum)
{
    int baseVal, tempSum;
    
    resultValue_t resultVal;
    
    //...
    if (tempSum == sum)
    {
        resultVal.valOne = array[index];
        resultVal.valTwo = array[nIndex];
        printf("%d + %d\n", resultVal.valOne, resultVal.valTwo);
    }
    //...
}

//version_3

typedef struct
{
    int valOne;
    int valTwo;
}resultValue_t;
resultValue_t resultVal;

标签: cstructmemory-management

解决方案


区别在于“存储期限”,即对象的生命周期。

在版本 1 中使用“分配的存储持续时间”。这意味着该对象在返回resultVal之后存在malloc,直到某些代码通过调用显式“杀死它” free。在大多数系统上,内存分配在称为堆的区域中。分配通常很慢(即除非有充分理由,否则不要使用它——见后文)。

在版本 2 中使用“自动存储期限”。这意味着对象resultVal一直存在,直到相关块的执行结束。在这种情况下,直到函数返回。换句话说 - 在这种情况下,对象resultVal在执行进入函数时自动创建,并在执行离开函数时自动销毁。在大多数系统上,内存分配在称为堆栈的区域中。分配通常非常快。

在版本 3 中使用“静态存储持续时间”。这意味着对象resultVal从执行开始到执行结束都存在。因此,可以从代码中的任何位置随时访问该对象。作为程序启动的一部分,内存通常分配在一些特殊区域,而且速度也非常快。

显然,所有 3 种类型都有用例。

通常应避免使用版本 3,但在某些特殊情况下静态对象是有意义的。使用时,通常最好使用关键字将它们的使用限制在“文件范围” static

在大多数情况下,您应该选择第 2 版,因为它既快速又安全。但是,如果对象的大小(在这种情况下resultVal)非常大,则应避免使用版本 2,因为存在堆栈溢出的风险。在这种情况下使用版本 1。

如果您希望对象在函数返回后“活着”,那么版本 1 也很有用(实际上是必需的)。free但是,在离开函数之前调用的问题中的示例并非如此。

结论:

由于resultValue_t;是一个相当小的对象类型,并且resultVal在函数调用后对象不需要“活着”,你应该选择版本 2。


推荐阅读