在函数中创建值,然后将指针保存在全局指针数组中的值上

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&amp;' from an rvalue of type 'int*' Test2(&amp;i); ^ main.cpp:27:6: note: in passing argument 1 of 'void Test2(int&amp;)' void Test2(int&amp;); ^ 一个明显的错误是您在test1 中调用test2 的方式:test2(&amp;i);。由于test2 是这样定义的 我将test2(int) 更改为test2(int*)。它现在可以工作(再次感谢),但它没有做它应该做的事情。我将即 20 放入 z 中。之后,Test 执行 20*20=400 并将其放入 int i。 i 的地址由 test2 写入全局。现在,cout &lt;&lt; *global[0] 应该是 400,但它是 2130567168。这是未签名/已签名的问题吗? @MaestroGlanz 请按原样更新代码,以便我查看 检查。我是堆栈交换的新成员(但有点像读者)。所以我必须熟悉所有的按钮和东西。顺便说一句,编辑功能非常天才。【参考方案2】:

在调用函数之前,编译器必须知道它。

所以你要么重新排列你的函数定义,使test2在前,test在后,main在后,或者你把test2test1的声明放在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&amp;。您可以通过将呼叫转为 test2(i); 来解决此问题。


一旦您的函数被整齐地拆分为声明和定义,就该执行典型的 C++ 源文件管理的下一步了:将声明放入头文件(通常是 *.h*.hpp)和 #include它们来自包含main 的实现文件(通常是*.cpp)。然后为这两个函数定义再添加两个实现文件。在那里也添加相应的#includes。不要忘记在标题中包含守卫。

最后,分别编译三个实现文件,并使用链接器从三个生成的目标文件中创建一个可执行文件。

【讨论】:

【参考方案3】:

你需要在调用它之前声明 test2。每个函数都需要在调用之前声明。

在 main 上方添加这些行来声明函数;

void test2(int& j);
void test2(int& j);

int main()...

【讨论】:

以上是关于在函数中创建值,然后将指针保存在全局指针数组中的值上的主要内容,如果未能解决你的问题,请参考以下文章

在循环中创建一个函数(指针?)

如何理解函数中的指针

将全局数组复制到由双指针引用的数组中

使用指针访问数组中的对象数据成员

将指向数组的指针传递给函数时出现分段错误(C++)

通过C中的void函数返回动态数组