繁体   English   中英

C和C ++中的指针和动态内存

[英]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 但是pGetPointer局部变量,因为指针本身是通过值传递给它的。

     +----+
     |    |
  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

对于GetPointer2GetPointer3您可以执行malloc

     +----+
     |    |
  yy +----+  malloc returns some other block

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM