这个int指针示例需要malloc吗?

时间:2015-02-19 17:54:28

标签: c pointers scope int malloc

以下应用程序适用于已注释掉的malloced int和仅使用int指针指向本地int“a”。我的问题是如果没有malloc这样做是否安全,因为当函数'doit'返回时,我认为int'a'超出范围,而int * p指向什么都没有。该程序是否由于其简单性而不是错误的,或者这完全可以吗?

#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 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

并非每个UB(未定义的行为)都会导致段错误。

通常情况下,堆栈的内存不会被释放回操作系统(但它可能会!),以便访问该内存。但是在下一个(更大的)函数调用中,指针指向的内存可能会被覆盖,因此您感觉安全的数据会丢失。

答案 2 :(得分:1)

函数调用中的 malloc()将起作用,因为它存储在堆上。 指针保持不变,直到释放内存为止。

是的,并非每个未定义的行为都会导致分段错误。

答案 3 :(得分:0)

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内存在所有平台上都无害:Can I avoid releasing allocated memory in C with modern OSes?

答案 4 :(得分:0)

是的,需要malloc,否则指针会指向堆栈的4字节空间,如果你调用其他函数或者现在创建局部变量,它将由其他数据使用。

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

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