我们总是需要在malloc / realloc之后检查指针是否为空?

时间:2015-10-20 04:13:52

标签: c pointers malloc realloc

我正在研究C,在一些代码示例中,我看到在为指针分配一些内存之后,我们必须检查指针是不是NULL。例如:

CVector *vector = malloc(sizeof(struct CVectorImplementation));
assert(vector != NULL);

另一个例子:

vector->elements = realloc(vector->elements, vector->elemsz * vector->vec_capacity);
assert(vector->elements != NULL);

但是,我认为既然已经分配了指针,那么它将分配的内存的地址作为其值,因此它总是必要的吗?为什么?

4 个答案:

答案 0 :(得分:2)

如果您已重新指定原始指针以响应realloc,那么为响应失败而做任何有用的事情都为时已晚。当realloc失败时,它会返回NULL,但它不会free原始指针。因此,即使您对分配失败(不常见)有一些合理的响应,您也已经泄露了您尝试realloc的内存。

您的主要问题的答案主要是"允许NULL指针取消引用是一个坏主意,因为它是漏洞的来源&#34 ;;通常,漏洞会出现在内核代码中(其中NULL和其他地方一样有效),但即使它不可利用,也意味着程序会出现段错误而不是报告有用的错误方式。

答案 1 :(得分:1)

realloc函数尝试分配新内存。如果此分配失败,则realloc函数将返回NULL。您的代码必须处理这种情况。

如果你想在这种情况下中止你的程序,那么你现在拥有的assert是合适的。如果您想要恢复,那么在评估情况时,您需要将realloc结果存储在单独的变量中,例如:

void *new = realloc(vector->elements, vector->elemsz * vector->vec_capacity);
if ( !new )
    // take some action.... the old vector->elements is still valid
else
    vector->elements = new;

答案 2 :(得分:1)

检查从malloc / realloc返回的指针是个好主意。 如果出现错误,您将返回null值。使用此检查对您有利,因为如果您稍后在程序中引用相同的指针并且程序突然崩溃,那么指针可能会设置为null。

如果你有一个来自malloc / realloc调用的有效指针,那么请确保在决定修改指针值之前和程序终止之前在free()函数中使用它,否则,你可能遇到内存泄漏。

如果您需要更改指针值以写入您分配的内存的不同部分,请使用另一个指针。

这是C中的代码,显示了我的意思:

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

int main(){
  char *block=calloc(1,10000);
  if (block==NULL){
      printf("Can't allocate memory\n");
      return -1;
  }
  memset(block,48,20); //set 1st 20 bytes of memory to number zero (ascii code 48)
  char *insideoftheblock=block+10; // I set a pointer to go to index #10 in the memory
  *insideoftheblock='x';
  *insideoftheblock++;
  *insideoftheblock='y';
  printf("Memory = '%s'",block);
  free(block);
}

<强> P.S。

我更新了我的代码以包含检查内存是否已实际分配。

答案 3 :(得分:0)

分配失败通常导致2个操作中的1个:

1)使用诊断程序退出程序。这比不检查和让代码继续谁知道什么更好。

2)在特定情况下,代码可以应对失败。也许释放其他资源并再次尝试,返回失败代码并将问题留给调用例程或写一个&#34;自杀记录&#34;并重新启动系统。 IAC,这一行动非常具体。

强大的代码检查结果。初学者代码没有。