在我整个CS职业生涯中忽略了C后,我决定试一试!
初始化变量时,我们可以:
int b = 0;
初始化b,为其分配内存,稍后我们可以用
更新它b = 2;
如果需要的话。
所以,原谅我这个荒谬的“noob”问题,但为什么我们需要这样的电话:
double *b = (double *) calloc(n, sizeof(double));
初始化变量时会为它分配空间吗?
为什么我们不能只做
double b = 0;
b* = b.addressOf(b) //or some similar construct.
这有什么用?
我试过谷歌搜索无效,所以请原谅我 - 很遗憾*在谷歌是一个通配符,因此很难找到相关的结果。
答案 0 :(得分:3)
在当前上下文中声明的变量在上下文结束时终止它们的生命周期。
分配内存为您提供了存储寿命较长变量的空间。
例如,
double *foo() {
double d;
return &d;
}
void bar() {
double *d = foo();
*d = 0.0;
}
将尝试访问不再存在的变量,因为它的生命周期是foo
函数。
C和C ++不跟踪对象。指针只指向对象,但不会延长对象的生命周期,因此即使指针不是NULL
,指针也完全有效。
但是,这是有效的:
double *foo() {
return (double *)malloc(sizeof(double));
}
void bar() {
double *d = foo();
*d = 0.0;
}
这将为double
分配内存,并将指针返回到内存,该内存在使用free
函数显式返回池之前保持有效。不将它返回池将导致内存泄漏。
答案 1 :(得分:0)
除非我完全弄错,否则在C中,calloc
或malloc
是实现动态数据结构的唯一可能性。
答案 2 :(得分:0)
关于变量分配,您可以这样做:
int a = 10
。这些变量在堆栈上定义,最有可能与使用它们的一些代码一起定义(这就是为什么在没有正确检查boudadries的情况下写入堆栈中声明的数组可能会很危险。您可能会覆盖代码)。变量还有一个范围:函数范围,全局范围和其他范围(例如if-else的if-branch)。它们使用起来很快,但它们或多或少都是静态的,并且它们具有您不需要清洁它们的巨大优势。它们由应用程序自动清理。但是它们有很大的缺点。堆栈空间比堆空间更有限。因此,您只能使用适度大小的变量(不要从字面上理解,而是对您的操作系统允许进行一些研究。对所有人来说,64KB是不够的。)。calloc()
或其他内存分配函数动态地在堆上。这些变量在称为堆或动态内存的区域中声明。这些变量将保留在那里,直到使用它们的应用程序退出(在这种情况下(现代)操作系统通常将内存回收给自己),或者它们free
使用free()
。你总是应该释放内存以避免内存泄漏。动态内存的优势在于(在现代操作系统上)可寻址内存远大于分配给堆栈空间的大小,因此您可以拥有更多,更大,更大的结构和数组。答案 3 :(得分:0)
范围是可以访问变量的代码的区域或部分。可以
实施例
#include<stdio.h>
void function1()
{
printf("In function1\n");
}
static void function2()
{
printf("In function2\n");
{
int i = 100;
Label1:
printf("The value of i =%d\n",i);
i++;
if(i<105)
goto Label1;
}
}
void function3(int x, int y);
int main(void)
{
function1();
function2();
return 0;
}
在示例中,
上例中的变量i
具有块范围。如果控件超出范围(生命结束),则变量消失。您无法访问该变量。
所以C提供了动态内存构造来访问这种场景中的内存。 例如:
int* function(void)
{
int *ptr = malloc(sizeof(int));
*ptr = 5;
return ptr;
}
int main(void)
{
printf("%d", function());
return 0;
}
即使变量printf
超出范围,ptr
仍会打印该值,但ptr
指向的内存仍然存在(有生命)。