我正在研究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);
但是,我认为既然已经分配了指针,那么它将分配的内存的地址作为其值,因此它总是必要的吗?为什么?
答案 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,这一行动非常具体。
强大的代码检查结果。初学者代码没有。