以下应用程序适用于已注释掉的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);
}
答案 0 :(得分:5)
是的,在函数不再在范围内后,取消引用指向本地堆栈变量的指针是未定义的行为。你碰巧不幸的是,在你再次尝试访问它之前,内存没有被覆盖,被释放回操作系统或者变成了一个指向恶魔工厂的函数指针。
答案 1 :(得分:3)
并非每个UB(未定义的行为)都会导致段错误。
通常情况下,堆栈的内存不会被释放回操作系统(但它可能会!),以便访问该内存。但是在下一个(更大的)函数调用中,指针指向的内存可能会被覆盖,因此您感觉安全的数据会丢失。
答案 2 :(得分:1)
是的,并非每个未定义的行为都会导致分段错误。
答案 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);
}
}