【问题标题】:Local variable address used as errno [closed]用作errno的局部变量地址[关闭]
【发布时间】:2012-07-12 11:31:42
【问题描述】:
#include<stdio.h>

struct a
{
    void *ptr;
    unsigned long val;
};

void main()
{
    unsigned char errno;

    struct a *id;
    id = malloc(sizeof(*id));
    func2(id);
    printf("After changing %d\n", id->val);
}


void func2(struct a *id)
{
    unsigned char errno;
    func(id,&errno);
}

void func(struct a *id,void *ptr)
{   
    memset(id, 0, sizeof(*id));

    id->ptr = ptr;
    if (sizeof(id->val) >= sizeof(id->ptr))
    {   
        id->val = (unsigned long)id->ptr;
        return;
    }

}

当我在主函数中打印 id->val 时,它正在打印 -1075050593 .但我试图访问一个无效的地址。请解释。我对 c 编程很陌生。

【问题讨论】:

  • 另外,您应该打开编译器警告消息。你会发现这段代码编译不干净。您应该先解决所有编译问题,然后再询问问题是否仍然无法按预期工作。
  • Pointer to local variable 的可能重复项
  • func2(&amp;id); 的 & 符号太多。并且 main() 应该返回 int。叹息。
  • 请注意errno 在 C 上下文中具有固定含义。
  • 您是否尝试在func2() 中打印errno 的值。它可能被初始化为 0,然后在 func() 中将 0 分配给 id-&gt;val

标签: c memory malloc local-variables


【解决方案1】:

通常,什么是“访问无效地址”?它由 2 个部分组成。 1、访问:包括读/写/执行。 2、无效地址:内核空间和未分配的堆是用户应用程序的无效地址。

在这种情况下,地址(&errno)属于堆栈,因此它不是无效地址。而且您不会读取/写入/执行此地址中的内容。所以你访问的不是无效地址。

顺便说一句,在 printf() 调用中使用“%d”占位符,“id->val”将被解释为带符号的 int 类型,这就是你得到负值的原因。请使用“%p”作为指针,使用“%u”作为无符号整数。

【讨论】:

  • 所以如果我尝试访问 *id->val 会有什么行为?
【解决方案2】:

以下语句不是试图访问无效地址,它只是打印地址

printf("After changing %d\n", id->val);

由于id 被错误地传递给func2(),它会保留什么值是未知的。

代码的一些问题(在cmets中已经提到了一些):

  • 在传递到func2() 时错误地获取id 的地址,因为id 已经是struct a*
  • 隐式声明 memset()malloc() 缺少包含指令
  • func()func2() 的隐式声明
  • main() 的返回类型应为int

【讨论】:

  • 我做了一个编辑而不是结构的地址,只有指针应该被传递。 printf("修改后 %d\n", id->val);它试图打印一个无效的地址。
  • @shunty,它只是 打印 地址值,并没有尝试访问它,这很好。见ideone.com/ZH3Ws
猜你喜欢
  • 1970-01-01
  • 2018-01-15
  • 2019-09-06
  • 2015-10-25
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 2021-09-14
相关资源
最近更新 更多