结构和内存管理,C
Structures and memory management, C
我想了解一些关于结构和内存管理的事情。我有三个版本代码,其结果是相同的。它们仅在结构的 definition/allocation 上有所不同。在版本一中,结构分配有此代码: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;
- 版本 1 从堆中分配内存。
- 版本 2 从堆栈分配内存。
- 版本 3 使用 bss 部分的内存(在我使用的每个编译器实现中,但它可能来自其他地方)。它也是唯一初始化对象的版本(在本例中为全零)。
区别在于“存储时长”,即对象的生命周期。
在版本 1 中使用“分配的存储持续时间”。这意味着对象 resultVal
存在于 malloc
returns 之后,直到某些代码通过调用 free
显式“杀死它”。在大多数系统上,内存分配在称为堆的区域中。分配通常很慢(即,除非有充分的理由,否则不要使用它 - 稍后见)。
在版本 2 中使用“自动存储持续时间”。这意味着对象 resultVal
一直存在,直到相关块的执行结束。在这种情况下,直到函数 returns。换句话说 - 在这种情况下,对象 resultVal
在执行进入函数时自动创建,并在执行离开函数时自动销毁。
在大多数系统上,内存分配在称为堆栈的区域中。分配通常非常快。
在版本 3 中使用“静态存储持续时间”。这意味着对象 resultVal
从执行开始到执行结束都存在。因此可以在代码中的任何位置随时访问该对象。作为程序启动的一部分,内存通常分配在一些特殊区域,而且速度也非常快。
显然这 3 种类型都有用例。
通常应避免使用版本 3,但在某些特殊情况下静态对象是有意义的。使用时,通常最好使用关键字 static
.
将它们的使用限制在“文件范围”
在大多数情况下,您应该选择版本 2,因为它既快速又安全。但是,如果对象的大小(在本例中 resultVal
)非常大,由于堆栈溢出的风险,应避免使用版本 2。在那种情况下使用版本 1.
如果您希望对象在函数 returns 之后“存活”,版本 1 也很有用(实际上是必需的)。然而,问题中的示例并非如此,因为在离开函数之前调用了 free
。
结论:
因为 resultValue_t;
是一个相当小的对象类型,并且对象 resultVal
在函数调用后不需要“活着”,你应该选择版本 2。
我想了解一些关于结构和内存管理的事情。我有三个版本代码,其结果是相同的。它们仅在结构的 definition/allocation 上有所不同。在版本一中,结构分配有此代码: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;
- 版本 1 从堆中分配内存。
- 版本 2 从堆栈分配内存。
- 版本 3 使用 bss 部分的内存(在我使用的每个编译器实现中,但它可能来自其他地方)。它也是唯一初始化对象的版本(在本例中为全零)。
区别在于“存储时长”,即对象的生命周期。
在版本 1 中使用“分配的存储持续时间”。这意味着对象 resultVal
存在于 malloc
returns 之后,直到某些代码通过调用 free
显式“杀死它”。在大多数系统上,内存分配在称为堆的区域中。分配通常很慢(即,除非有充分的理由,否则不要使用它 - 稍后见)。
在版本 2 中使用“自动存储持续时间”。这意味着对象 resultVal
一直存在,直到相关块的执行结束。在这种情况下,直到函数 returns。换句话说 - 在这种情况下,对象 resultVal
在执行进入函数时自动创建,并在执行离开函数时自动销毁。
在大多数系统上,内存分配在称为堆栈的区域中。分配通常非常快。
在版本 3 中使用“静态存储持续时间”。这意味着对象 resultVal
从执行开始到执行结束都存在。因此可以在代码中的任何位置随时访问该对象。作为程序启动的一部分,内存通常分配在一些特殊区域,而且速度也非常快。
显然这 3 种类型都有用例。
通常应避免使用版本 3,但在某些特殊情况下静态对象是有意义的。使用时,通常最好使用关键字 static
.
在大多数情况下,您应该选择版本 2,因为它既快速又安全。但是,如果对象的大小(在本例中 resultVal
)非常大,由于堆栈溢出的风险,应避免使用版本 2。在那种情况下使用版本 1.
如果您希望对象在函数 returns 之后“存活”,版本 1 也很有用(实际上是必需的)。然而,问题中的示例并非如此,因为在离开函数之前调用了 free
。
结论:
因为 resultValue_t;
是一个相当小的对象类型,并且对象 resultVal
在函数调用后不需要“活着”,你应该选择版本 2。