我在C ++工作,最近一直在使用指针。我发现有几种方法可以初始化我需要使用的内存块。
void functioncall(int* i)
{
*i = *i + 1;
}
int main(){
int* a = (int*)malloc(sizeof(int));
int az = 0;
functioncall(a);
functioncall(&az);
}
请注意,第一个变量int * a被声明为指针,然后我为它内存了malloc。但是,使用az它不是指针,但在调用函数时,我得到了内存的地址。
所以,我的问题是:是否有一种首选的方式=,或者是否有任何一种惩罚?
答案 0 :(得分:7)
int* a = (int*)malloc(sizeof(int));
这会在堆上分配内存。你必须自己解除分配,否则你会遇到内存泄漏。您可以通过调用free(a);
来解除分配。这个选项绝对比较慢(因为必须要求内存并且必须完成其他一些背景操作),但只要你自由呼叫就可以使用内存。
int az = 0;
这会在堆栈上“分配”内存,这意味着当你离开声明的函数时它会被自动销毁(除非是一些非常罕见的例外)。你不必整理记忆。此选项更快,但您无法控制对象何时被销毁。
答案 1 :(得分:3)
a
被放到堆上,az
在堆栈上。你负责释放内存的堆。当堆栈超出范围时,它会自动释放。所以答案是当你想要放置数据时,如果你需要放在范围的末尾。
PS你应该在C ++中使用new
答案 2 :(得分:1)
一般情况下,当相当容易时,你应该避免动态内存分配(malloc
,calloc
,new
):它们比堆栈分配慢,但更重要的是,你必须记住手动释放(free
,delete
)通过动态分配获得的内存,否则会导致内存泄漏(如代码中所示)。
答案 3 :(得分:1)
我不确定你要做什么,但几乎没有
为此分配单个int
(也不是int
数组的原因
物)。您functioncall
中至少有两个错误:
首先,它无法检查空指针(如果指针不能
null,通过引用传递),其次,它没有做任何事情:它
递增作为参数传递的指针的副本,然后
取消引用初始值并抛出读取的值。
答案 4 :(得分:0)
直接在堆栈上分配小变量通常更快,因为您不必执行任何堆操作。与指针相关的螺旋上升的可能性也较小(例如,双重释放)。最后,你使用的空间更少。除了开销之外,你还在移动一个指针和一个int。
答案 5 :(得分:0)
第一行(int * a = ...)被称为动态分配变量,如果您在运行时之前不知道需要多少变量,或者根本不需要它,通常会使用它。
第二行(int az = 0)称为自动变量,它更经常使用。
答案 6 :(得分:0)
int az = 0;
functioncall(a);
就行为而言,这没关系。
int* a = (int*)malloc(sizeof(int));
functioncall(&az);
当你执行*i++
时,它会在函数内部调用undefined-behavior(UB)。由于malloc
仅分配内存,因此不初始化内存。这意味着,*i
仍然未初始化,读取未初始化的内存会调用UB;这解释了为什么*i++
是UB。如果你知道的话,UB是C ++中最危险的东西,因为它意味着任何事情都可能发生。
至于原来的问题,你更喜欢什么?所以答案是,首选自动变量而不是指针(分配为malloc
或new
)。
自动意味着快速,清洁和安全。
答案 7 :(得分:0)
func(typename * p)
指针是调用值
* p ++是* p和p ++
如果更改此指针,则不更改原始。