这是指针吗? (如果是这样,它是如何初始化的?)

时间:2012-03-22 02:55:42

标签: c++ c

有一个头文件esU​​til.h,它带有一个名为ESContext的结构的定义,其成员之一是userData。 userData是指向void的指针。

使用它的程序的主体就是这样,简要说明:

#include "esUtil.h"

typedef struct {
 GLuint programObject;
} UserData;

int DoSomething(ESContext *esContext) {
 UserData *userData = esContext->userData;

 ...
}

int main(int argc, char *argv[]) {
 ESContext esContext;
 UserData userData;

 esStart(&esContext);
 esContext.userData = &userData;

 ...
 if(!DoSomething(&esContext))
  return 0;

 ...
}

我对语句中的“* userData”感到困惑:UserData * userData = esContext-> userData;

如果它是一个指针,它是如何在没有被声明的情况下产生的。谢谢你的任何解释。

4 个答案:

答案 0 :(得分:6)

是的,它是一个指针。这条线

UserData *userData = esContext->userData;

声明一个名为userData的变量,其类型为UserData *(指向UserData的指针),并使用值esContext->userData对其进行初始化。

答案 1 :(得分:1)

代码中某些位置可能会使用结构UserData初始化ESContext的成员userData,这也就是为什么它被分配给DoSomething函数中的UserData指针。

它可能是一个void指针,但它仍然可以保存UserData对象的地址

答案 2 :(得分:1)

userData确实是一个指针。它被声明为指针类型(类型名称中的星号是一个提示),并且此代码可能是编译的,因此它必须是指针类型。除非您未使用userData(主要)发布任何代码,否则userData尚未初始化。

你问“它是如何在没有被初始化的情况下产生的。”好吧,在主流的C / C ++实现中,指针实际上只是整数,其大小等于系统上的字大小(32位系统为32位,64位系统为64位)。如果取消引用指针,CPU将转到指针所代表的地址,并获取相关数据。如果数据不存在,你的程序会变成kaboom(在* nix,segfaults上),如果你很幸运,如果你没有,那就很奇怪。在这种情况下,声明了main userData,因此实际上存在数据。但是,它没有初始化,因此userData的内容可能是任何内容。只要DoSomething不使用userData的内容,就可以,因为它只是操纵该地址。但是如果它试图取消引用userData,CPU就会出现内存并引入垃圾,此时程序可能会做各种奇怪的事情,因为在userData内可能有任何位模式,所以userData上的任何计算都可能会产生各种不同的结果。

C / C ++语言规范说使用未初始化的值会给出未定义的行为,实际上是未定义的,这意味着编译器可以插入代码来擦除硬盘,或者向Kernighan发送威胁消息Ritchie,或者在你使用未初始化的值时做任何喜欢的事情。但实际编译器生成的代码只是给出了垃圾位模式(通常是先前函数调用的剩余堆栈数据)。因此,虽然使用未初始化的值错误,但它不会杀死你。

关于未初始化值和错误指针的所有这些奇怪之处是C和C ++是不安全语言的最明显的方式之一。 Eric Lippert解释了C和C ++不安全的另一种方式here

答案 3 :(得分:1)

它是一个指针,它由这一行初始化:

esContext.userData = &userData;