typedef struct {
char *title;
char *desc;
} RoomData;
RoomData roomData;
GameGetCurrentRoomTitle(roomData.title);
//INSIDE THE GAME.C FILE
int GameGetCurrentRoomTitle(char *title) {
title = &gameData.title[0];
return strlen(title);
}
因此,出于某种原因,当我调用GameGetCurretRoomTitle()函数时,它无法正确打印出roomData.title的内容,它会打印出NULL。但是当我打印出“标题”时函数本身内部的var工作...我已经包含了所有正确的文件,标题,并且所有语法在完整代码中都是正确的...
答案 0 :(得分:1)
C
使用pass-by-value进行函数参数传递。如果要从roomData.title
函数更改GameGetCurrentRoomTitle()
变量本身的值,则必须将指针传递给roomData.title
。然后,您可以使用strdup()
将gameData.title[0]
的内容复制到title
内的GameGetCurrentRoomTitle()
。你需要记住以后释放指针。
否则,您可以将内存分配给title
,然后再将其传递给GameGetCurrentRoomTitle()
,然后在GameGetCurrentRoomTitle()
内使用strcpy()
从gameData.title[0]
复制字符串。< / p>
您需要累计更改GameGetCurrentRoomTitle()
功能。
答案 1 :(得分:1)
函数的参数是其局部变量。您可以想象这个函数定义
int GameGetCurrentRoomTitle(char *title) {
title = &gameData.title[0];
return strlen(title);
}
及其电话
GameGetCurrentRoomTitle(roomData.title);
像
GameGetCurrentRoomTitle(roomData.title);
//...
int GameGetCurrentRoomTitle() {
char *title = roomData.title;
title = &gameData.title[0];
return strlen(title);
}
退出该函数后,其本地变量标题将被销毁。
如果您希望更改原始指针,则必须传递其地址。在这种情况下,函数定义及其调用将类似于
GameGetCurrentRoomTitle( &roomData.title );
//...
int GameGetCurrentRoomTitle( char **title ) {
*title = &gameData.title[0];
return strlen( *title );
}
答案 2 :(得分:0)
在函数内设置变量的值不会改变调用者中变量的值。
您需要使用strcpy将标题复制到传递给函数的缓冲区中。不要只是改变本地指针。
答案 3 :(得分:0)
假设gameData.title
是指向char
数组
然后gameData.title[0]
保存一个指向存储在“某处”的char
数组的指针。让我们说标题是“Foobar”,这就是它在记忆中的位置:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
假设标题之前和之后的字节或char
s在此时刻被程序取消设置并且未使用,并且上面的空插槽就意味着它。< / p>
现在,让我们调用指向char
gameData.title[0]
p1
的{{1}}数组的指针。它指向“Foobar”char
数组,如下所示:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-----------+
|
[ ][ ][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]
指针p2-p4是char
数组中gameData.title
个指针的其余部分。
现在,您的场景中还有2个有趣的指针。首先,roomData.title
char
指针。为简单起见,我们称之为pA
。当您将其传递给GameGetCurrentRoomTitle
时,它会被取消设置并指向内存空间中未定义的char
:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+------------+
|
[ ][pA][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]
|
+---------+
|
v
[ ][ ][ ][ ]
其次,GameGetCurrentRoomTitle
标题char
指针参数。为简单起见,我们称之为pB
。将pA
作为参数传递给GameGetCurrentRoomTitle
时,其值将复制到pB
。它的值不是它指向的内存的内容,而是它指向的地址。这意味着pB
将指向内存空间中与char
相同的未定义pA
:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-------------+
|
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
| |
+---------+--+
|
v
[ ][ ][ ][ ]
接下来,在GameGetCurrentRoomTitle
的正文中,您重新分配pB
(本地标题char
指针)以指向与p1
相同的内存位置(指向char
中的gameData.title[0]
数组:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+------+------+
| |
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
|
+---------+
|
v
[ ][ ][ ][ ]
并且,当GameGetCurrentRoomTitle
最终返回其调用者时,pA
仍然指向相同的未定义内存位置。
您错过的修复方法是将指针传递给pA
而不是GameGetCurrentRoomTitle
本身而不是pA
本身,而不是重新分配pB
要指向与p1
相同的内存位置,您应该取消引用 pB
并将p1
分配给该内存位置,这是内存位置所在的内存位置存储pA
变量。这样,当GameGetCurrentRoomTitle
返回时,pA
会看到您期望的字符串。
对于“图形”,新情况是pB
不指向char
数组,而指向指针指向char
阵列。我们知道pA
是指向char
数组的指针:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-------------+
|
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
^ |
| |
+------------+
通过为解除引用的pB
分配内容,您可以有效地分配它指向的内存位置,而不是pB
本身。因此,将p1
分配给引用的pB
与在此方案中将其分配给pA
相同:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-----+-------------+
| |
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
在代码中:
GameGetCurrentRoomTitle(&roomData.title); // pass pointer to 'pA'
int GameGetCurrentRoomTitle(char **title) // 'pB' is a pointer to pointer
{
*title = &gameData.title[0]; // assign 'p1' to dereferenced 'pB'
return strlen(*title); // measure dereferenced 'pB'
}