这个 int 指针示例需要 malloc 吗?
Is malloc needed for this int pointer example?
以下应用程序既可以使用注释掉的 malloced int,也可以使用 int 指针指向本地 int 'a.'我的问题是如果没有 malloc 这样做是否安全,因为我认为当函数 'doit' returns 时 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);
}
是的,在函数不再在范围内后取消引用指向局部堆栈变量的指针是未定义的行为。你只是碰巧不够幸运,内存没有被覆盖,释放回 OS 或者在你再次尝试访问它之前变成一个指向恶魔工厂的函数指针。
并非每个 UB(未定义行为)都会导致段错误。
通常,堆栈的内存不会释放回 OS(但它可能会!)以便访问该内存。但是在下一次(更大的)函数调用中,指针指向的内存可能会被覆盖,因此您认为 bing 安全的数据丢失了。
p
没有指向 doit
中的 return 上的任何内容并不重要。
因为,你知道,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?
是的,需要malloc
,否则指针将指向堆栈的4字节space,如果您调用其他函数或创建,该指针将被其他数据使用现在是局部变量。
你可以看到,如果你之后用值 10 调用那个函数:
void use_memory(int i)
{
int f[128]={};
if(i>0)
{
use_memory(i-1);
}
}
函数调用中的 malloc() 将起作用,因为它存储在堆上。
指针将一直保留,直到您释放内存。
是的,并非所有未定义的行为都会导致分段错误。
以下应用程序既可以使用注释掉的 malloced int,也可以使用 int 指针指向本地 int 'a.'我的问题是如果没有 malloc 这样做是否安全,因为我认为当函数 'doit' returns 时 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);
}
是的,在函数不再在范围内后取消引用指向局部堆栈变量的指针是未定义的行为。你只是碰巧不够幸运,内存没有被覆盖,释放回 OS 或者在你再次尝试访问它之前变成一个指向恶魔工厂的函数指针。
并非每个 UB(未定义行为)都会导致段错误。
通常,堆栈的内存不会释放回 OS(但它可能会!)以便访问该内存。但是在下一次(更大的)函数调用中,指针指向的内存可能会被覆盖,因此您认为 bing 安全的数据丢失了。
p
没有指向 doit
中的 return 上的任何内容并不重要。
因为,你知道,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?
是的,需要malloc
,否则指针将指向堆栈的4字节space,如果您调用其他函数或创建,该指针将被其他数据使用现在是局部变量。
你可以看到,如果你之后用值 10 调用那个函数:
void use_memory(int i)
{
int f[128]={};
if(i>0)
{
use_memory(i-1);
}
}
函数调用中的 malloc() 将起作用,因为它存储在堆上。 指针将一直保留,直到您释放内存。
是的,并非所有未定义的行为都会导致分段错误。