2011-11-29 70 views
3

我接触到指针int* i,其中我只知道它的内存已分配,但不确定它是否已被初始化为某个整数。如何检查分配的内存是否被初始化

如果我尝试尊重它,会发生什么?换句话说,我应该如何检查它是否被初始化?如果不是,我想为该地址分配一个整数值;否则我什么都不做。

+2

如果内存分配给它,它初始化,但可能会因内存是如何分配的有随机垃圾数据。 – birryree

+0

可能重复:http://stackoverflow.com/questions/1576300/checking-if-a-pointer-is-allocated-memory-or-not – jasso

+1

雷蒙德陈先生说[IsBadXxxPtr的确可以称为CrashProgramRandomly(HTTP:// blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx) – ephemient

回答

5

定义“初始化”。总是会有一些价值,你无法判断这个值是垃圾还是整数,因为任何32位的垃圾都会产生一些价值。你可以解除引用它,没问题。

0

我接触到的指针INT * 1,其中我只知道它的内存是 分配,但我不知道它已被初始化为某个整数或 没有。

如果我被分配为一个指针,并没有初始化,你会得到一个段违反。如果我是分配和初始化一些整数X ...即

int X = SOMEVALUE; 

    int* i; 
    i = &X; // It would seem silly to malloc a single int... 

它被初始化当且仅当X被初始化。如果您知道它指向的值的某些预期范围,那么建议您在使用之前执行边界检查...

如果我尝试遵从它,会发生什么?换句话说,我应该如何检查它是否被初始化?如果不是,我想 为该地址分配一个整数值;否则我什么都不做。

我的典型做法是将指针初始化为0或NULL,直到我有一个真正的值来提供它们。在此之前调用somesort的* X *页头功能......那么,如果它的任何地方我会尝试使用它......我做了...

if (myPtr == NULL) 
{ 
printf("Run failure handling code...\r\n"); 
return FUNC_FAILED_CONST; 
} 

但我必须要更多的信息,以了解你的情况....

0

良好的编程习惯包括将NULL分配给未初始化的指针。如果你正在处理别的地方的指针,通常检查它以确保它不是NULL。你的情况:

if (i != NULL) 
    *i = the_int_you_assign; 

但是,如果处理它没有特定的方式,你不能在良好的编程习惯算的话,你真的不能为自己辩护。

0

i通常是整数(通常为int)对象的名称。调用指针i令人困惑。

因此,让我们假设你有

int *p; 

你说“它的内存分配”。你指的是指针对象本身的内存(当你声明p时分配的内存),还是指它指向的int对象的内存?

无论哪种情况,您都无法判断它是否已被初始化。

如果p具有静态存储持续时间,则它的初始值(在没有显式的初始化的)是一个空指针;它没有指向任何东西。否则,它的初始值是垃圾,除了为它分配一些有效值之外,你不能安全地执行。

另一方面,如果您的意思是p已被初始化为指向一些int对象,但该对象可能已经初始化,也可能未初始化,那么您也有类似的问题。如果您有:

int *p; 
p = malloc(sizeof *p); 
if (p == NULL) { 
    /* malloc() failed! */ 
    exit(EXIT_FAILURE); 
} 

然后p指向一个分配int对象,但该对象的值是垃圾。在大多数系统中,您可以安全地访问该值(*p) - 但这样做毫无意义。但有可能int具有陷阱表示;如果是这样,只是访问*p的值具有未定义的行为,并可能导致程序崩溃。优化编译器可以在未定义的对象存在的情况下做出意想不到的事情;它可以假设它已被初始化为某个值,并且不费心去实际获取存储值。

没有特殊的值,标记,或用于未初始化的int对象标志。程序员完全可以确保任何对象在尝试访问它之前具有有效的值。

所以你问的;(在C. C是不是这些语言之一当然,很多这些语言的实现都写(非常仔细地)一些语言跟踪这些东西给你。)错误的问题。如果你不知道一个对象是否已经被初始化,那么解决方案是找出(逻辑上,当你编写代码时,而不是在程序执行期间)是否已经初始化。这样做的最佳方法通常是确保已初始化为

如果你试图做类似下面的伪代码:

if (/* *p has been initialized */) { 
    do something with *p; 
} 
else { 
    do something else; 
} 

,那么你就错了。相反:

/* Ensure p points to a valid int object */ 
*p = some_value; 
/* Now you *know* *p has been initialized */ 
do something with *p; 
0

您也可以在这样的重新定义malloc的方式,它会分配的内存块,并通过使用这样的宏观其初始化一次零个字节:

#define malloc(p, size) do {if (p != NULL) {p=malloc(size); memset(p, 0, size);}} while(0); 

或者如果你喜欢在条款的malloc可以重新定义的calloc

#define malloc(p, elCount , elSize) do {if (p != NULL) {p=calloc(elCount,elSize);}} while(0); 

通过迫使这种结构,你一定会认为它使用的malloc()任何程序员 - 还初始化内存正确,以便没有指针显示垃圾数据。

+0

为什么你比'calloc'更喜欢这个? – jasso

+0

我不知道。是的 - 'malloc()'宏可以用'calloc'来写。这只是一个例子,如何重写标准的malloc函数,以便如果开发人员试图使用* malloc *的旧定义 - 他们得到关于不同malloc签名的编译时错误,因此被迫使用calloc()或重新定义正确malloc()或者他们想欺骗 - 他们也可以将宏重新定义为标准(但我不指望这一点,因为在C中你有很多可能性来欺骗所有的东西:-(所以必须是真诚地开发的某种程度的协议) –

+0

对不起,我有点不清楚,我的意思是,如果你想将malloc定义为一个像calloc一样的宏,是否有任何偏好为什么在宏中使用memset而不是在宏中使用calloc? – jasso