双指针作为函数参数

问题描述 投票:1回答:2

当这个函数出现时,我正在阅读"Understanding and Using C Pointers"页面:

void safeFree(void **pp) {
  if (pp != NULL && *pp!= NULL) {
    free(*pp);
    *pp = NULL;
  }
}

以及它的示例代码:

int main(int argc, char **argv) {
  int* pi = (int*)malloc(sizeof(int));
  *pi = 5;
  safeFree((void**)&pi);

  return EXIT_SUCCESS;
} 

我的观点是,在这种情况下检查pp != NULL条件下的if是没用的,对吧?因为根据编写此代码的方式,这种情况永远不会是错误的。但有一种情况,这种情况将成立,假设**pp期望一个内存地址和(假设我)一个变量的内存地址永远不会是NULL?或者作者做过那次检查,以防有人做过这样的事情?

int main(int argc, char **argv) {
  int **pi = NULL;
  safeFree((void**)pi);

  return EXIT_SUCCESS;
}

谢谢。

c pointers free
2个回答
0
投票

虽然说safeFree只是令人困惑,并没有提供安全。因为代码假定API用户将始终传递特别构造的指针。考虑这些:

tricky 0 (screws up a)

#include <stdio.h>
#include <stdlib.h>


void safeFree(void **pp) {
  if (pp != NULL && *pp!= NULL) {
      free(*pp);
      *pp = NULL;
  }
}

int main() {
    int *a;
    int **p;
    a = malloc(5 * sizeof(int));
    p = malloc(1 * sizeof(a));
    a[0] = 10;
    p[0] = a;
    fprintf(stderr, "%d\n", a[0]);
    safeFree((void **)p); /* grrrr */
    fprintf(stderr, "%d\n", a[0]);
}

tricky 1 (crashes)

int main() {
    int a[] = { };
    int b[] = { 1 };
    int c[] = { 2 };

    int **p = malloc(3 * sizeof(int *));
    p[0] = a, p[1] = b, p[2] = c;

    safeFree((void **)p); /* grrrr */
}

0
投票

该函数主要检查NULL,例如你的第二个。如果传递了一个实际的变量地址,那么检查不会失败,但永远不会相信你的调用者是理智的。

© www.soinside.com 2019 - 2024. All rights reserved.