这是 Stroustrup 最新版本的“C++ 编程语言”中的一个问题。
在过去的几天里,我一直在考虑这个问题。
我唯一能想到的(这可能是不正确的)是这样的:
int* f(int n) {
int* a = &a - n * sizeof(int*);
return a;
}
我的意图是获取堆栈中更高位置的地址。这有道理吗?还有其他人有其他答案吗?请记住,这在第 5 章(指针、数组和结构)中,所以答案不应该涉及本书后面的内容。
这是 Stroustrup 最新版本的“C++ 编程语言”中的一个问题。
在过去的几天里,我一直在考虑这个问题。
我唯一能想到的(这可能是不正确的)是这样的:
int* f(int n) {
int* a = &a - n * sizeof(int*);
return a;
}
我的意图是获取堆栈中更高位置的地址。这有道理吗?还有其他人有其他答案吗?请记住,这在第 5 章(指针、数组和结构)中,所以答案不应该涉及本书后面的内容。
我在 C 代码中经常使用的一个例子是:
C *c = (C*) malloc(sizeof *c);
...
free(c);
它涉及指针和结构。当然,通过在 C++ 中说代替,new
您不必使用该成语。new C
我知道的唯一(勉强)合理的情况是,当您想将指向对象本身的指针传递给其构造函数时。例如,假设您有一个循环链表节点:
class Node
{
public:
Node(Node* next): next(next) {}
private:
Node* next;
};
并且您想在堆栈上创建一个单元素循环列表。你可以这样做:
Node n(&n);
其他一些不太实用的例子(即我不明白你为什么需要那种东西),但在其他方面是有效的:
int n = sizeof(n);
void* p = &p;
考虑一个整数类型的数组,它应该在第一个元素中保持其大小:
// clang++ --std=c++11 initializer.cpp -o initializer
#include <iostream>
using namespace std;
void Print(int* array) {
cout << "array has " << *array << " elements" << endl;
for(int count {*array}; count; --count) {
cout << *++array << endl;
}
}
int main(int, char* []) {
{
int elements[] {sizeof(*elements), 1, 2, 3};
*elements = sizeof(elements) / *elements - 1;
Print(elements);
}
cout << "---" << endl;
{
int elements[] {sizeof(*elements)};
*elements = sizeof(elements) / *elements - 1;
Print(elements);
}
return 0;
}
输出:
./initializer
array has 3 elements
1
2
3
---
array has 0 elements
PS GitHub 中的示例:第 8 章:练习 9.3
我认为这是一个正确的方法。只是你需要照顾很多事情:)
首先,您不需要sizeof因为 n 将乘以a的大小。基本上,您必须选择正确的指针类型才能在堆栈上获取所需的地址。
int* a = &a - n; // so if n==1 => a = &a - (1*4)
char* b = &b - n; // so if n==1 => b = &b - (1*1)
其次,您必须注意字节顺序。
另外,我不确定我是否忘记了什么:)
首先,不能保证堆栈的增长方向。您的代码假定它会增长,但它也可能会增长(即,降低地址)。此外,有些东西放在堆栈上,您可能不知道(返回地址、堆栈帧、寄存器等),并且在尝试抓取堆栈上更高的东西时不会“跳过”过去。
你最终想要做什么?