【问题标题】:Pointers to stack堆栈指针
【发布时间】:2013-01-20 06:51:21
【问题描述】:

很抱歉,我不能用一些代码来支持我的问题(我不明白如何构造它,所以它会在这里被接受),但我还是尝试了。

如果我理解正确,引用相同类型结构的结构将需要使用包含的指针来执行此操作以供参考。这个指针可以引用堆栈(而不是堆)上分配的空间而不产生分段错误吗? -

这应该如何声明?

【问题讨论】:

  • 申报时没有什么特别需要做的。指针是指向堆栈、堆还是 NULL 对包含它的结构的声明方式没有影响。

标签: pointers memory stack


【解决方案1】:

是的,您可以使用指向堆栈上变量的指针,但前提是提供该堆栈帧的方法尚未返回。例如,这将起作用:

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

但事实上,它已经坏了。

【讨论】:

  • 感谢您的回答。我相信我明白为什么它应该被打破 - 但为什么它仍然有效?
  • 这很可能是因为自从函数返回以来堆栈没有被重用,因此之前的所有内容仍然有效。如果在两者之间调用了其他函数(带有堆栈变量),那么它肯定会失败。
【解决方案2】:

你没有说你正在使用什么语言,所以现在从你的问题的措辞中假设 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 */
}

【讨论】:

  • 如果pStr1 未初始化(处理malloc 行时的情况),sizeof(*pStr1) 会起作用吗?
  • 是 - sizeof 在编译时进行评估,无需初始化内容即可知道它们有多大。
【解决方案3】:

不确定这是否是一个专门的 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

【讨论】:

  • 伟大而详尽的答案:)
  • @dexter,如果这个或任何其他答案对您有帮助,那么请投票(使用答案左侧的向上箭头)和/或接受它(使用绿色勾号,也可以答案的左边)。
猜你喜欢
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2017-06-06
相关资源
最近更新 更多