关于指针的一些问题

时间:2014-05-05 18:15:25

标签: c++ pointers

我现在是高中三年级,我正在学习C ++。 由于我们已经完成了我们需要了解的一般编程(循环,if语句,函数,结构,数组和二维数组),我们启动了二进制/文本文件,我想我们学习文件学习内存管理。 首先,我现在正在努力学习指针,因为如果我理解正确的话,在OOP中它们是必须的。 其次,我想知道计算机是如何工作的,背后发生了什么。 现在,我制作了这段小代码

int main()
{
    char y;
    char *x;
    x = &y;
    cout << "Write a word: ";
    cin >> x;
    cout << x << endl;
    system("pause");
    return 0;
}

它可以工作,但是当程序关闭时,我得到一个错误,表示变量'y'周围的堆栈已损坏。 如果我没有混淆,堆栈是动态内存,堆是静态内存,考虑到我收到此错误,因为当程序关闭时变量y不在内存中。 我在正确的道路上吗?

另外,还有一个问题。 我无法理解何时以及为什么我应该使用指针,例如:

int main()
{
    int number = 10;
    int* pointer;
    pointer = &number;
    *pointer = 15;
    cout << *pointer << endl;
    system("pause");
    return 0;
}

为什么我不能简单地这样做:

int main()
{
    int number = 10;
    number = 15;
    cout << number << endl;
}

我为什么要使用指针?另外,我不明白为什么如果我创建一个char *并分配它,例如“hello”它写的是hello而不是h。 基本上,通过声明一个char *我声明一个大小未知的数组,对吧?请告诉我它到底发生了什么。

2 个答案:

答案 0 :(得分:5)

  

当程序关闭时,我收到一个错误,表示变量'y'周围的堆栈已损坏

因为>>通过接受整个字符串来响应char*。指针必须指向足够大的缓冲区来保存该字符串,但它只指向堆栈变量x>>不知道这一点,所以它只是提前收费并写入堆栈上x旁边的任何内容。

实际上,在这种情况下你最好使用std::string

std::string s;
std::cin >> s;

cin读取一个单词。

  

为什么我不能简单地这样做

你可以。在这个简单的程序中你不需要指针,但是你需要它们才能获得更高级的东西。即使你不经常使用它们(现代C ++有许多设施可以通过更安全和更简单的结构替换字符串),但仍然有助于知道std::string,例如,使用指针实现:它实际上是{ {1}}包含在一个类中,为您处理char*之类的事情。该类知道>>指向何处并调整它,如果它需要更多空间来存储额外的字符。

答案 1 :(得分:2)

在第一部分中,您将y声明为单个char:不是它们的数组。因此,当您尝试阅读一个单词时,只有第一个字母&#34;适合&#34;在单个char空间内。读入的其余字符实际上会溢出&#34;你为它分配的空间,给你那些错误。

如果您想要更多字母,则需要将y定义为char的数组,因此:

char* y = new char[50]; // Create an array of 50 chars, on the HEAP, not the stack

char y[50]; // Create an array of 50 chars, on the STACK, not the heap.

将STACK视为您家中的一个区域。你的房子不是很大,但它足够大,你可以做大部分必要的事情。你可以在房间的一个角落里堆放50个盒子,当你离开房间时,你的女仆会出现并为你摆脱所有剩余的盒子。你不必手动清理它们。

将HEAP视为一个非常大的存储柜。您和计算机上运行的所有其他程序共享此存储柜中的空间。无论何时你需要一些额外的空间,你都可以租用&#34;在它里面的一个小房间,给它一张纸,上面写着房间的(记忆)地址。这张纸可以复制,所以任何想要进入你的盒子的朋友都可以这样做。

所以你去储物柜,要求一个可容纳50箱的房间。他们给你一张纸,上面写着那个房间的(记忆)地址。你可以随意使用那个房间里的那些盒子:它是你的。

您甚至可以将您房间的地址告知您的朋友x。您的朋友x可以访问这些框,更改框内的内容,然后使用您房间的内容前往城镇。但x无法更改您房间的位置。如果他愿意,x也可以与他人共享该房间的(记忆)地址。

现在,你已经完成了房间的使用。如果您丢失了房间地址的纸张,房间仍会分配您的姓名。但是你不能再访问它了,因为你不知道它的地址。但如果您的朋友仍然有您的纸张副本,他们仍然可以访问您房间的内容。这就像分配char *y = new char[50]然后简单地退出该功能而不首先删除y一样。

如果每个人都把你的房间的地址丢弃在房间的地址上,那么房间仍然在那里,你现在已经泄漏了内存,并且已经分配了它,但没有人指出它。它将在您的程序生命周期内保持未使用状态。

让我们说,在你完成房间之前,你告知存储经理它可以自由清理:你搬出去了。经理取消注册你的房间:你没有&#34;泄露的记忆。&#34;这就像关闭函数之前使用delete [] y一样。

有一点需要注意的是,仍然可能发生一些不好的事情:如果您或您的朋友x仍未在存储管理员注册后指向该房间,并且您尝试访问它现在,这成了一个问题:盒子可能仍然在那里,但是其他人现在正在消耗一些(或全部)空间的机会很大,而且你正在查看他们的内容房间。你想避免这种情况。

你的例子中的所有内容都只是简单的说法,并且给我的朋友一个内存的地址。&#34;当然,您可以访问它,但现在朋友也可以指向它。