代码之家  ›  专栏  ›  技术社区  ›  user740521

这个int指针示例是否需要malloc?

  •  2
  • user740521  · 技术社区  · 11 年前

    下面的应用程序既可以使用注释掉的mallocated int,也可以使用int指针指向本地int‘a’我的问题是,如果没有malloc,这样做是否安全,因为我认为当函数“doit”返回时,int“a”超出了范围,留下int*p指向任何对象。程序是否由于其简单性而没有seg错误,或者这是完全正确的?

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct ht {
        void *data;
    } ht_t;
    
    ht_t * the_t;
    
    void doit(int v)
    {
        int a = v;
        //int *p = (int *) malloc (sizeof(int));
        //*p = a;
        int *p = &a;
    
        the_t->data = (void *)p;
    }
    
    int main (int argc, char *argv[])
    {
        the_t = (ht_t *) malloc (sizeof(ht_t));
        doit(8);
        printf("%d\n", *(int*)the_t->data);
        doit(4);
        printf("%d\n", *(int*)the_t->data);
    }
    
    5 回复  |  直到 11 年前
        1
  •  5
  •   IllusiveBrian    11 年前

    是的,在函数不再在作用域中之后取消引用指向本地堆栈变量的指针是未定义的行为。你只是很不幸,在你尝试再次访问之前,内存没有被覆盖,没有被释放回操作系统,或者没有变成指向鼻子工厂中恶魔的函数指针。

        2
  •  3
  •   glglgl John Dvorak    11 年前

    并非所有UB(未定义行为)都会导致segfault。

    通常,堆栈的内存不会被释放回操作系统(但它可能!),这样访问内存就可以工作了。但是在下一次(更大的)函数调用时,指针指向的内存可能会被覆盖,因此您觉得安全的数据会丢失。

        3
  •  1
  •   Vamsi    11 年前

    函数调用中的malloc()可以工作,因为它存储在堆上。 指针将一直保留,直到释放内存。

    是的,并不是所有未定义的行为都会导致分割错误。

        4
  •  0
  •   Community Mohan Dere    9 年前

    这无关紧要 p 从返回时不指向任何内容 doit .
    因为,你知道, p 也没有了。

    读取指向中不再存在的对象的指针并不重要 main 虽然这是UB,但在大多数现代平台上无害。
    更糟糕的是,你正在阅读它曾经指向的不存在的对象,它是直的 Undefined Behavior .

    尽管如此,没有人必须抓住你:
    Can a local variable's memory be accessed outside its scope?

    作为补充, Don't cast the result of malloc (and friends) .
    此外,请注意 free -ing内存在所有平台上都不是无害的: Can I avoid releasing allocated memory in C with modern OSes?

        5
  •  0
  •   benaryorg    11 年前

    是的 malloc 否则指针将指向堆栈的4字节空间,如果您调用其他函数或立即创建本地变量,则其他数据将使用该空间。

    您可以看到,如果您稍后使用值10调用该函数:

    void use_memory(int i)
    {
        int f[128]={};
        if(i>0)
        {
            use_memory(i-1);
        }
    }