很抱歉,我不能用一些代码来支持我的问题(我不明白如何构造它,所以它会在这里被接受),但我还是尝试了。
如果我理解正确,则引用相同类型的结构的结构需要使用包含的指针来执行此操作以供参考。这个指针可以引用堆栈(而不是堆)上分配的空间而不产生分段错误吗?-
这应该如何声明?
你没有说你正在使用什么语言,所以现在从你的问题的措辞中假设 C ......以下代码是完全有效的:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t str1;
str_t str2;
str1.pNext = &str2;
在此示例中,str1 和 str2 都在堆栈上,但如果其中一个或两个都在堆上,这也可以工作。您唯一需要注意的是堆栈变量超出范围时将被删除,因此如果您已动态分配 str1 并将其从函数中传回,您将不希望 str1->pNext 指向该函数中堆栈上的东西。
换句话说,不要这样做:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t *func(void)
{
str_t *pStr1 = malloc(sizeof(*pStr1));
str_t str2;
pStr1->pNext = &str2;
return pStr1; /* NO!! pStr1->pNext will point to invalid memory after this */
}
是的,您可以使用指向堆栈上变量的指针,但前提是提供该堆栈帧的方法尚未返回。例如,这将起作用:
typedef struct
{
int a;
float b;
} s;
void printStruct(const s *s)
{
printf("a=%d, b=%f\n", s->a, s->b);
}
void test()
{
s s;
s.a = 12;
s.b = 34.5f;
printStruct(&s);
}
然而,这将导致错误,因为堆栈帧会消失:
s *bad()
{
s s;
s.a = 12;
s.b = 34.5f;
return &s;
}
编辑:好吧,我说它会导致错误,但是在调用该代码时:
int main()
{
test();
s *s = bad();
printStruct(s);
return 0;
}
我在编译期间收到警告:
s.c:27:5: warning: function returns address of local variable [enabled by default]
并且该程序似乎运行良好:
$ ./s
a=12, b=34.500000
a=12, b=34.500000
但事实上,它已经坏了。
不确定这是否是一个专门的 C/C++ 问题,但无论如何我都会以 C/C++ 代码为例。
你可以声明它的唯一方法:(有细微的变化)
typedef struct abc
{
struct abc *other;
} abc;
other
可以指向堆栈上的一个对象,如下所示:
abc a, b; // stack objects
b.other = &a;
这不是关于范围的问题,因此我将跳过对执行上述操作可能出现的问题的评论。
但是,如果您想将其分配给动态创建的对象,则该对象不可能在堆栈上。
abc b;
b.other = malloc(sizeof(abc)); // on the heap