[英]Pointers and dynamic memory in C and C++
几天前,我不得不使用C,在使用指针时,我感到有些惊讶。
C中的示例:
#include <stdio.h>
#include <stdlib.h>
void GetPointer(int* p) {
p = malloc( sizeof(int) );
if(p) {
*p = 7;
printf("IN GetPointer: %d\n",*p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
}
void GetPointer2(int* p) {
if(p) {
*p = 8;
printf("IN GetPointer2: %d\n",*p);
} else {
printf("INVALID PTR IN GetPointer2");
}
}
int* GetPointer3(void) {
int* p = malloc(sizeof(int));
if(p) {
*p = 9;
printf("IN GetPointer3: %d\n",*p);
} else {
printf("MALLOC FAILED IN GetPointer3\n");
}
return p;
}
int main(int argc, char** argv) {
(void) argc;
(void) argv;
int* ptr = 0;
GetPointer(ptr);
if(!ptr) {
printf("NOPE\n");
} else {
printf("NOW *PTR IS: %d\n",*ptr);
free(ptr);
}
int* ptr2 = malloc(sizeof(int));
GetPointer2(ptr2);
if(ptr2) {
printf("NOW *PTR2 IS: %d\n",*ptr2);
free(ptr2);
}
int* ptr3 = GetPointer3();
if(ptr3) {
printf("NOW *PTR3 IS: %d\n",*ptr3);
free(ptr3);
}
return 0;
}
输出:
IN GetPointer: 7
NOPE
IN GetPointer2: 8
NOW *PTR2 IS: 8
IN GetPointer3: 9
NOW *PTR3 IS: 9
在此示例中,第一个指针在GetPointer
方法内部仅具有“值”。 为什么在内部使用malloc
仅在方法的生命周期内有效?
我在C ++中进行了尝试,并得到了相同的行为。 我认为它会保留其价值,但不会。 不过,我找到了解决方法:
void GetPointer(int*& p) {
p = new int;
if(p) {
*p = 7;
printf("IN GetPointer: %d\n",*p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
}
在CI中无法做到这一点。 有没有办法在C中做同样的事情,或者在尝试给它赋值之前,我必须小心并“ malloc”指针?
如果要在C中重新分配指针指向的内容,则必须使用int**
,即指向指针的指针。
那是因为指针是通过值作为参数复制的,因此,如果希望在指针指针的更改在函数范围之外是可见的,则需要另一种间接方式。
这个
void GetPointer(int* p) {
p = malloc( sizeof(int) );
if(p) {
*p = 7;
printf("IN GetPointer: %d\n",*p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
}
绝对不会造成内存泄漏。
它不执行任何操作的原因是您将指针的副本传递给函数(int * p),如果要更改p指向的内容,则需要传递指针的地址。
void GetPointer(int** p)
void GetPointer(int** pp) {
int *p = malloc( sizeof(int) );
if(p) {
*p = 7;
printf("IN GetPointer: %d\n",*p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
*pp = p;
}
在void GetPointer(int* p)
中,一旦退出功能块,您将丢失指向动态内存的指针。
尝试使用指针到指针方法:
GetPointer(int ** p) {
*p = malloc( sizeof(int) );
if(*p) {
**p = 7;
printf("IN GetPointer: %d\n",**p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
}
对于第一次调用GetPointer,您需要传递一个指向int的指针。 (与C ++不同,C ++允许在函数签名中使用&运算符进行引用传递,C始终按值传递内容,这意味着您的代码会将ptr
的副本传递给GetPointer
函数。)您需要传递地址该指针的长度(即指针ptr
在内存中的存储位置,以便GetPointer方法内的代码可以在该位置放置某些内容,从而修改ptr
本身。
即呼叫应该是:
GetPointer(&ptr);
并且函数应如下所示:
void GetPointer(int** p) {
*p = malloc( sizeof(int) );
if(*p) {
**p = 7;
printf("IN GetPointer: %d\n",**p);
} else {
printf("MALLOC FAILED IN GetPointer\n");
}
}
p = malloc( sizeof(int) );
malloc( sizeof(int));
将返回一个指针,然后将其分配给p
。 但是p
是GetPointer
局部变量,因为指针本身是通过值传递给它的。
+----+
| |
xx +----+ malloc returns this block
+----+
| |
xx +----+ local variable p is assigned this block
+----+
| 7 |
xx +----+ p modifies value of this block
函数结束,因此p
留下内存泄漏
+----+
| 7 |
xx +----+ No one points to it anymore
对于GetPointer2
和GetPointer3
您可以执行malloc
,
+----+
| |
yy +----+ malloc returns some other block
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.