C语言内存思考题

C语言内存思考题

去企鹅面Python后台职位,悲剧的是一面笔试题除了一个正则,全部算法题,还要求得用C写。小白我4+年没有碰C了,知识早还给老师了,死了一地脑细胞。有个题随便蒙的,记录一下

看代码说出Test函数运行结果.

void GetMemory(char *p)
{
    p=(char*)malloc(100);
}

void Test(void)
{
    char *str=NULL;
    GetMemory(str);
    strcpy(str,"Hello world");
    printf(str);
}
用子函数申请动态内存成功,但是主函数得不到该内存,因为无法把内存首地址传递给主程序,子函数只是使用了一下主函数的指针值,并不能返回给主程序,运行strcpy一句时会程序崩溃。

void GetMemory(char **p,int num)//二级指针
{
    *p=(char*)malloc(num);
}

void Test(void)
{
    char *str=NULL;
    GetMemory(&str,100);//&str,取指针自身的地址
    strcpy(str,"hello");
    printf(str);
}
能够输出hello,内存泄漏。

char *GetMemory(void)
{
    char p[]="hello world";//此行将p[]改成*p就对了,此时p[]存在于栈里边,*p的话字符串存于常量区
    return p;
}

void Test(void)
{
    char *str=NULL;
    str=GetMemory();
    printf(str);
}
 可能是乱码。p[]是栈内指针,子函数调用结束时,它占用的栈内存就被释放了,主函数输出的是随机的内容.

void Test(void)
{
    char *str=(char*)malloc(100);
    strcpy(str,"hello");
    free(str);
    if(str!=NULL)
    {
        strcpy(str,"world");
        printf(str);
    }
}
通常会打印出world.小白我这本机实验,打印出world,啥事没有。

free(str)之后,str不是null,而是指向一块随机内存,也叫野指针。然后不明所以就往这块随机内存写值,后果也就呵呵了,非常危险。那为啥小白我这没出故障呢?找了一下,解释如下:

这是因为进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的。

free之后一定要手动设置指针为null
### C语言笔试题目中的内存管理常见问题解析 #### 函数返回局部数组地址的问题 考虑如下函数定义: ```c char *GetMemory(void) { char p[] = "hello world"; return p; } ``` 此代码尝试返回一个局部字符数组 `p` 的地址。然而,在调用者环境中使用该返回值是不安全的,因为当 `GetMemory()` 执行完毕后,栈上的临时对象即被销毁,所指向的数据可能不再有效[^1]。 #### 结构体成员对齐与填充字节的影响 对于带有特定数据类型的结构体声明, ```c struct tagTest1 { short a; /* 2 bytes */ char d; /* 1 byte */ long b; /* 4 bytes */ long c; /* 4 bytes */ }; ``` 在应用了 `#pragma pack(4)` 编译指令之后,编译器会按照指定边界调整字段布局并插入必要的填充字节以满足对齐要求。因此即使原始总长度不足16字节,实际占用空间也可能达到或多于预期尺寸[^2]。 #### 指针初始化不当引发的风险 下面的例子展示了未适当初始化指针所带来的隐患: ```c struct student { char *name; int score; } stu, *pstu; strcpy(stu.name, "Jimy"); // name 这个成员没有指向合法地址,malloc分配前不可写入 ``` 这里试图复制字符串到尚未通过 `malloc` 或其他方式获得的有效内存位置上,这可能导致程序崩溃或行为异常[^3]。 #### 静态存储区的特点及其应用场景 静态变量和全局变量均位于进程启动时就已准备好的固定区域内,它们在整个应用程序生命周期内持续存在直到结束为止。这类资源适合用于那些需要保持状态跨越多个函数调用的情形[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值