指针值更改C++

pointer value change C++

本文关键字:C++ 指针      更新时间:2023-10-16

我在编程C++也相对较新。当我在处理一个关于使用字符指针数组传递参数的代码时。我遇到了一个问题,即在某些操作后,指针的值发生了变化。下面是我的代码。

#include <iostream>
using namespace std;
void input(char* argv[], int &i)
{
char buff[10][20]; //buffer string array
while (cin.peek() != 'n') {
cin >> buff[i++];
}
for (int j = 0; j < i; j++) {
argv[j] = buff[j];
}
argv[i] = NULL; // putting a NULL at the end 
}
int main(int argc, char* argv[])
{
char *arg[10];
int i = 0;
input(arg, i); //input the arguments
for (int j = 0; j < i; j++) {
cout << arg[j] << endl;  //output the arguments entered
}
return 0;
}

子函数void input(char* argv[], int &i)应该允许我输入多达 9 次参数或在按下回车键时输入参数。而i表示参数的总数。

然后将参数存储为字符指针数组,然后将其传递回主函数的char *arg[10]以保存。

但是,我发现之后cout << arg[j] << endl;arg的值将丢失,并且正在打印随机值。

您正在创建堆栈上buff字符的二维数组,然后通过argv参数将指针返回到该数组中。 但是buff存在于堆栈上,一旦input函数退出,它就不复存在。buff使用的内存将被您在调用input后调用的其他函数覆盖。

您应该在main中分配buff,然后将其传递到input以便它在input返回后继续存在于main范围内。

另一种选择是为input中的buff分配堆空间。在这种情况下,main函数将负责在完成内存后释放内存。

显然,您可以使用更高级的C++功能来避免其中一些开销。虽然这是一个C++程序,但它实际上是写成C的。但是,了解内存和指针的工作原理对于理解较新的C++功能解决的问题至关重要。

我的指针的值发生了变化

指针是唯一没有损坏的东西。问题是他们指向的内存。

可以通过打印每个指针的值来证明第一部分,或者只是在调试器中检查它们。(您可以通过强制转换为 void 来打印地址而不是它指向的 C 字符串,如cout << static_cast<void*>(arg[j]) << 'n')。

那么你的 C 字符串怎么了?好吧,您在函数input中声明了一个自动作用域数组变量。当函数退出时,该数组将不复存在,就像任何其他自动作用域变量一样。在变量不复存在后,访问变量曾经存在的内存是非法的。

您在此数组中返回指针的事实并不意味着在数组本身超出范围后通读(取消引用)它们并不合法,这实际上是未定义的行为。

被覆盖的内容实际上是最好的情况,因为这意味着你注意到了这个错误:它可能在法律上崩溃,或者更糟糕的是,在你提交/部署/出售程序之前,它似乎完美地工作,并且此后每次运行都崩溃。

将堆栈视为大量(但不是无限)内存。只需向下和向上移动stack pointer即可分配和释放它(方向将取决于硬件)。

下面是带有一些注释的代码。

input(arg, i);
// when you get here the stack pointer will have been moved up, freeing the space
// that was allocated for 'buf' in 'input'
// the space for 'j' could overwrite the space where 'buf' was
for (int j = 0; j < i; j++) {
// the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
cout << arg[j] << endl;
}