在函数中创建值,然后将指针保存在全局指针数组中的值上
Posted
技术标签:
【中文标题】在函数中创建值,然后将指针保存在全局指针数组中的值上【英文标题】:create value in function, then save pointer on value in global pointer array 【发布时间】:2016-03-24 21:19:28 【问题描述】:我对 c++ 比较陌生,并且习惯于 Java(我更喜欢 Java)。 我这里有一些指针问题。我创建了一个最小程序来模拟更复杂程序的行为。
这是代码:
void test (int);
void test2(int*);
int* global [5]; //Array of int-pointer
int main(int argc, char** argv)
int z = 3;
int y = 5;
cin >> z; // get some number
global[0] = &y; // global 0 points on y
test(z); // the corpus delicti
//just printing stuff
cout << global[0]<<endl; //target address in pointer
cout << &global[0]<<endl; //address of pointer
cout << *global[0]<<endl; //target of pointer
return 0; //whatever
//function doing random stuff and calling test2
void test (int b)
int i = b*b;
test2(&i);
return;
//test2 called by test puts the address of int i (defined in test) into global[0]
void test2(int* j)
global[0]= j;
棘手的部分是test2。我将在测试中创建的变量的地址放入全局指针数组中。不幸的是,这个程序给了我一个编译器错误:
main.cpp: In function 'int test(int)':
main.cpp:42:20: error: 'test2' was not declared in this scope
return test2(&i);
^
我在这里找不到任何范围问题。我尝试将 test 的 int i 更改为全局变量,但没有帮助,所以我想,这不是原因。
编辑:它现在可以编译,但为 cin = 20 提供了错误的值。 *global[0] 应该是 400,但是是 2130567168。这似乎不是 int/uint 问题。它离 2,14e9 太远了。 Edit2:输入值无关紧要。
【问题讨论】:
即使您修复了此代码以进行编译,您仍然会存储一个指向立即超出范围的临时指针... 请避免全局/类变量持有传递函数的临时状态。我认为这是代码混淆。 实际上最终的程序应该实例化一个VI-Object(见NI-VIs)。指向该对象的指针应全局保存,以防止该对象在函数离开后被删除。对象应保留在内存中。我想,这是被禁止的。如果我将全局数组从指针更改为 VI-Object,程序分配的内存是一个 VI-Object 的 300 倍(仅用于一种类型的 VI-Object)。即使我只使用一个条目。但我希望程序仅在创建 VI 对象时分配内存。 【参考方案1】:'test2' was not declared in this scope
这是因为编译器不知道test2
是什么。您需要在 main 上方添加一个函数原型。
void test (int b);
void test2(int& j);
或者只是:
void test (int);
void test2(int&);
因为此时编译器只需要知道参数的类型而不是它们的名称。
编辑:将函数定义移到 main 上方而不添加原型也可以,但最好使用原型。
【讨论】:
非常感谢。在Java中我不需要这个。而且我仍然不明白为什么,但是如果编译器需要,它会得到它。但是仍然有一个残余错误,我没有得到。或者我的谷歌搜索表明,这正是我想做的事情是不允许的。 :桌面后面的愤怒的人:那就是错误:main.cpp: In function 'void test(int)': main.cpp:42:13: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int*' Test2(&i); ^ main.cpp:27:6: note: in passing argument 1 of 'void Test2(int&)' void Test2(int&); ^
一个明显的错误是您在test1
中调用test2
的方式:test2(&i);
。由于test2
是这样定义的
我将test2(int)
更改为test2(int*)
。它现在可以工作(再次感谢),但它没有做它应该做的事情。我将即 20 放入 z 中。之后,Test 执行 20*20=400 并将其放入 int i。 i 的地址由 test2 写入全局。现在,cout << *global[0]
应该是 400,但它是 2130567168。这是未签名/已签名的问题吗?
@MaestroGlanz 请按原样更新代码,以便我查看
检查。我是堆栈交换的新成员(但有点像读者)。所以我必须熟悉所有的按钮和东西。顺便说一句,编辑功能非常天才。【参考方案2】:
在调用函数之前,编译器必须知道它。
所以你要么重新排列你的函数定义,使test2
在前,test
在后,main
在后,或者你把test2
和test1
的声明放在main
之前:
void test2(int& j); // declaration
void test(int b); // declaration
int main(int argc, char** argv)
// ...
void test(int b) // definition
// ...
void test2(int& j) // definition
// ...
这将揭示一个更严重的错误;您使用int*
调用test2
,但它需要int&
。您可以通过将呼叫转为 test2(i);
来解决此问题。
一旦您的函数被整齐地拆分为声明和定义,就该执行典型的 C++ 源文件管理的下一步了:将声明放入头文件(通常是 *.h
或 *.hpp
)和 #include
它们来自包含main
的实现文件(通常是*.cpp
)。然后为这两个函数定义再添加两个实现文件。在那里也添加相应的#include
s。不要忘记在标题中包含守卫。
最后,分别编译三个实现文件,并使用链接器从三个生成的目标文件中创建一个可执行文件。
【讨论】:
【参考方案3】:你需要在调用它之前声明 test2。每个函数都需要在调用之前声明。
在 main 上方添加这些行来声明函数;
void test2(int& j);
void test2(int& j);
int main()...
【讨论】:
以上是关于在函数中创建值,然后将指针保存在全局指针数组中的值上的主要内容,如果未能解决你的问题,请参考以下文章