C ++:int * j出了什么问题; * J = 50; ?

时间:2011-07-31 03:16:32

标签: c++ c pointers

这是一个新手C ++指针问题。我不知道为什么会发生这种情况......

我发现如果我写这段代码。这完全有效。

代码1

int *j;    //create an pointer j
*j = 50;   //assign 50 to the *j, meaning value pointed by address 50 is xxx

然而,当我想尝试使它更简单时。编译器给我这个错误信息。

代码2

int *j = 50; //i guess this should be the same with Code1...

编译错误

error: invalid conversion from ‘int*’ to ‘int’

那为什么会那样?

6 个答案:

答案 0 :(得分:13)

那里的C语法有点含糊不清。

int *j = 50;

相当于

int *j;
j = 50;

实际上,你在第一段代码中所做的是危险的,因为在为它分配值之前你还没有为j分配任何内存。你需要像这样为它做记忆:

C中的

int *j = (int*) malloc(sizeof(int));
*j = 50;

在C ++中

int *j = new int;
*j = 50;

或者将指针指向已经有效的其他内存块:

int k;
int *j = &k;
*j = 50;
printf("%d", k); // 50

编辑:值得指出的是,歧义与'*'符号有关。在声明中,int *j; * j表示“一个名为j的指针”。但是当您在第二行“* j = 50”中使用它时,*将成为取消引用符号,表示“地址j处的值”。

答案 1 :(得分:2)

他们完全有不同的含义。

第一个声明指针,并将int中当前地址指向的j设置为50。没有其他背景,这已经很糟糕; j中的地址未初始化,您最有可能通过将值写入内存中的随机位置来导致分段错误。

第二段代码声明了一个指针,并将存储在其中的地址定义为50.如果你把它分开,就像写一样(注意第二个语句中没有星号):

int *j; j = 50;

答案 2 :(得分:2)

声明int *j;后,在堆栈上分配了int *类型的空间(在本例中),该空间具有一些地址addr_stk并且内容我们不知道,即。垃圾。

 +--------+          +--------+
 |  ???   |----+     |  xxx   |     trying to store 50 here
 +--------+    |     +--------+
 |   j    |    |     |        |
 +--------+    |     +--------+
 |addr_stk|    +---->|  ???   |     have no permission to access this location
 +--------+          +--------+

当您使用*j = 50;时,指针变量(对象)j的内容将用作在其中存储值50的地址。因此,您尝试将值50存储在具有垃圾地址值的某个地址位置,这意味着它可以位于任何位置。每当您尝试访问未分配给您的内存位置时,将无法存储或访问该位置,操作系统将阻止您进行操作并抛出一些错误。

您需要做的是首先用一些有效的地址初始化指针变量j。这可以通过首先使用malloc分配一些内存然后使用它来完成。或者使用其他变量(本地或全局)的地址初始化j。像

int *j, i;
j = &i;
*j = 50;

int *j;
j = malloc (sizeof (int));
*j = 50;

在访问*j的情况下,我们在j内有一个有效地址,因此使用j的内容作为地址(指针访问),有效,为{{1解析为有效的内存访问。

重要的是,当您使用*j分配内存时,应始终释放内存。这是一个好习惯,否则在大型程序中会导致内存泄漏。

答案 3 :(得分:1)

你的两个例子都错了。

第一个:

int *j;
*j = 50;

50存储到地址j。但是,您从未初始化j,因此您只是存储到未知地址。有时这会“成功”,有时这会使你的应用程序崩溃,有时它只会破坏你的应用程序状态而不会导致错误;它永远不是你真正想要做的。

第二个:

int *j = 50;

尝试使用类型为“int”的值初始化“pointer-to-int”类型的变量,这是一个错误。

相反,你想做类似的事情:

int i = 50;
int *j = &i; // j is now a pointer to i.

或:

int i;
int *j;
j = &i;  // note: no * before j.  j now contains a valid address.
*j = 50; // store 50 to the address j.  After this, i == 50.

答案 4 :(得分:1)

*是变量的类型的一部分,而不是其名称

int* j表示“我有一个名为j的变量,它是指向int的指针。”

int* j = 50(代码2)的意思是“我有一个名为j的变量,它是指向int的指针,并且应该使用值50”进行初始化。这是不允许的;如果没有显式强制转换,指针可能无法使用0以外的整数值进行初始化。 如果你不知道自己在做什么,明确地去解决这个问题是一个非常非常糟糕的想法,如果你问这些问题,那么你肯定不知道自己在做什么足以尝试

您应该能够从错误消息中找出这一点。无效的转换就是:您的代码尝试从一种类型转换为另一种类型(通过赋值),这是无效的。您分配的内容不是您所分配的兼容类型。它告诉你所涉及的类型是什么。

*j = 50(代码1中的第二行)表示“在50指向的位置”写入值j。这很糟糕,因为j尚未初始化。 这被称为“未定义的行为”并且正是如此 - 它可能以任何方式失败,或者不会失败,但即使它似乎有效也总是错误。但它会编译,并且大多数编译器甚至不会试图警告你这种事情,除非你问他们真的很高的警告水平 - 如果有的话。

答案 5 :(得分:0)

int *j = 50

实际上等于

int *j;
j = 50;

因为初始化的分配无论如何都会分配变量itsel。

在这两种情况下,这都是一个非常糟糕的主意,因为指针无效。