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

Pointers and dynamic memory in C and C++

本文关键字:动态 内存 指针      更新时间:2023-10-16

几天前,我不得不使用C,在使用指针时,我有些惊喜。

C:

中的一个示例
#include <stdio.h>
#include <stdlib.h>
void GetPointer(int* p) {
  p = malloc( sizeof(int) );
  if(p) {
    *p = 7;
     printf("IN GetPointer: %dn",*p);
  } else {
    printf("MALLOC FAILED IN GetPointern");
  }
}
void GetPointer2(int* p) {
  if(p) {
    *p = 8;
     printf("IN GetPointer2: %dn",*p);
  } else {
    printf("INVALID PTR IN GetPointer2");
  }
}
int* GetPointer3(void) {
  int* p = malloc(sizeof(int));
  if(p) {
    *p = 9;
    printf("IN GetPointer3: %dn",*p);
  } else {
    printf("MALLOC FAILED IN GetPointer3n");
  }
  return p;
}
int main(int argc, char** argv) {
  (void) argc;
  (void) argv;
  int* ptr = 0;
  GetPointer(ptr);
  if(!ptr) {
    printf("NOPEn");
  } else {
    printf("NOW *PTR IS: %dn",*ptr);
    free(ptr);
  }
  int* ptr2 = malloc(sizeof(int));
  GetPointer2(ptr2);
  if(ptr2) {
    printf("NOW *PTR2 IS: %dn",*ptr2);
    free(ptr2);
  }
  int* ptr3 = GetPointer3();
  if(ptr3) {
    printf("NOW *PTR3 IS: %dn",*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: %dn",*p);
  } else {
    printf("MALLOC FAILED IN GetPointern");
  }
}

在C中,我无法做这个问题。是否有一种方法可以在C中进行相同的操作,或者我必须小心并在尝试给出价值之前" malloc"指针?

如果要重新分配指针在C中指向的内容,则必须使用int**,即指向指针的指针。

这是因为指针是按值复制为参数的,因此,如果希望在Pointee中进行的更改在功能范围之外可见,您需要另一个间接级别。

这个

void GetPointer(int* p) {
  p = malloc( sizeof(int) );
  if(p) {
    *p = 7;
     printf("IN GetPointer: %dn",*p);
  } else {
    printf("MALLOC FAILED IN GetPointern");
  }
}

绝对没有什么部分与创建内存泄漏有关。

它不做任何事情的原因是,如果您想更改P点的指点,您需要将指针的副本传递给函数(INT* P)。/p>

void GetPointer(int** p)

void GetPointer(int** pp) {
    int *p = malloc( sizeof(int) );
    if(p) {
        *p = 7;
        printf("IN GetPointer: %dn",*p);
    } else {
        printf("MALLOC FAILED IN GetPointern");
    }
    *pp = p;
}

在void GetPointer(int* p)中,当您退出功能块时,您就会失去指向动态内存的指针。

尝试使用指针进行指针方法:

GetPointer(int ** p) {
  *p = malloc( sizeof(int) );
  if(*p) {
    **p = 7;
     printf("IN GetPointer: %dn",**p);
  } else {
    printf("MALLOC FAILED IN GetPointern");
  }
}
  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

对于第一个调用GetPointer,您需要将指针传递给指向INT的指针。(与C 不同,C 允许在功能签名中使用&amp;运算符传递的引用,C总是按值传递,这意味着您的代码正在以ptr copy 中传递到GetPointer函数中。)您需要传递该指针的地址(即,在内存中的位置ptr存储的,以便GetPointer方法中的代码可以将某些内容放在该位置,从而修改ptr本身。<<<<<<<<<<<<<<<<

即。电话应该是:

GetPointer(&ptr);

,功能应该看起来像:

void GetPointer(int** p) {
  *p = malloc( sizeof(int) );
  if(*p) {
    **p = 7;
     printf("IN GetPointer: %dn",**p);
  } else {
    printf("MALLOC FAILED IN GetPointern");
  }
}