从GetMemory()看C/C++内存分配机制

库力索法半导体C++岗 笔试题 库力索法半导体C++岗笔试题1.题目#include<stdio.h>char * GetMemory(void) { char p[] = "hello world"; return p; }int main() { char * str; str = GetMemory(); printf("%s",str); return 0; }Questio 阅读详情

先看下面一段代码

#include<iostream>

using namespace std;

void GetMemory(char *p, int num)
{
	p=new char[num];
}

void main()
{
	char *str=NULL;
	GetMemory(str,100);
	strcpy(str,"hello world!");
	cout<<str<<endl;
}

平台是windows 7+ VC6.0  ,编译通过,链接通过,但是程序运行的时候却崩溃了。原因就在于GetMemory(str,100)传递的是str的副本,所以str并没有被分配到内存,str依然指向NULL.而strcpy(char * strDest,const char * strSrc)的源码中并没有检查strDest是否为空,最终导致程序的崩溃。

正确的做法应该是传递指针的指针,代码如下:

#include<iostream>

using namespace std;

void GetMemory(char **p, int num)
{
	*p=new char[num];
}

void main()
{
	char *str=NULL;
	GetMemory(&str,100);
	strcpy(str,"hello world!");
	cout<<str<<endl;
}
使用了双重指针**p。将str的地址传进去。 这个比较难理解,其实可以这样看。在调用GetMemory(&str,100)的时候,&str=p,那么*p就是str,**p就是指向str的指针了,然后为**p申请空间,就是*p=new char【num】;
当然还可以用另外一种方法,通过返回地址空间的指针,

代码如下

#include<iostream>

using namespace std;

char* GetMemory(char *p, int num)
{
	p=new char[num];
	return p;
}

void main()
{
	char *str=NULL;
	str=GetMemory(str,100);
	strcpy(str,"hello world!");
	cout<<str<<endl;
}
以上两种,无论是用new  或者使用malloc()申请内存,都是在堆中分配内存,堆中分配的内存使用完后要及时释放,否在会造成内存泄露,看下面两种在栈中的内存分配:


#include<iostream>

using namespace std;

char* GetMemory()
{
	char str[]="hello world!";
	return str;
}

void main()
{
	char* p=GetMemory();
	cout<<p;
}
打印出来时乱码,这就在于函数中分配的内存存在于栈中,函数调用结束后,栈就被释放了,所以*p依然指向栈中的一个地址,但栈中的内容又不断变化,所以就指向了一个不确定的代码。

#include<iostream>

using namespace std;

char* GetMemory()
{
	char *str="hello world!";
	return str;
}

void main()
{
	char* p=GetMemory();
	cout<<p;
}
但是这样就可以,可能是*str分配的内存不在栈中吧,有知道的可以告诉我。


C#调用C++ DLL实战指南:从P/Invoke原理到混合编程避坑 在Windows平台软件开发中,跨语言互操作是解决性能瓶颈与复用遗留代码的关键技术。其核心原理是通过动态链接库(DLL)作为二进制接口,实现托管代码(如C#)与非托管代码(如C++)的通信。技术价值在于能充分发挥C++在计算密集型任务、硬件操作及复用现有资产方面的优势,同时保留C#在快速开发与用户交互上的高效性。应用场景广泛,包括图像处理、硬件驱动调用、集成历史核心库等。本文聚焦于C#通过P/Invoke调用C++ DLL的工程实践,深入解析两种主流导出方式:导出稳定的C风格函数与通过封装调用C++类。针对 阅读详情

相关推荐

C语言动态内存管理:从malloc/free原理到内存泄漏防范实战

动态内存管理是C语言编程的核心概念,它允许程序在运行时按需申请和释放内存,突破了静态内存分配在编译时确定大小的限制。其原理基于堆内存区域的管理,通过malloc、calloc、realloc等函数进行内存分配,并由free函数负责释放,赋予程序处理不确定数据规模的能力。这项技术的核心价值在于实现灵活的数据结构(如链表、动态数组)和资源管理,是构建高效、可扩展系统的基石。在实际应用场景中,如网络通信缓冲区、文件处理和大规模数据处理,动态内存管理至关重要。然而,手动管理也带来了内存泄漏、悬空指针等挑战,需要开发

cuixie2370的博客 391

Getmemory函数详解--内存操作的理解

题目:void GetMemory(char *p) { p = (char *)malloc(100); } void Test(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); } 请问运行Test 函数会有什么样的结果? 分析:程序崩溃。因为GetMem

jacky的博客 1万+

【无标题】

GetMemory 函数中:p 是在栈上分配的数组,当函数 GetMemory 返回时,p 将被销毁,因此返回的指针实际上指向的是一个已经无效的内存地址。1:函数参数传递的是值拷贝,因此在GetMemory()函数中,修改 p 并不会影响到 Test 函数中的原始指针,其次,在 Test 函数中尝试使用未初始化的指针 str,这可能导致未定义的行为。关于函数传递,是值传递还是地址传递,以及函数内分配的内存都是在栈上分配的,堆栈内存区的问题。提供先进的推理,复杂的指令,更多的创造力。

qq_41904287的博客 952

【面试题】关于GetMemory的故事

#include using namespace std; void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(char) * num); } void main() { char *str = NULL; GetMemory(str,100); strcpy(str,"Hello"); } //编译通过,但运行

Life Coding 1278

C/C++ 笔试面试(3)——内存管理GetMemory

1.关于动态申请内存的问题 出现率极高 程序的局部变量存在于(栈)中 程序的全局变量存在于(静态存储区)中 程序动态申请的数据存在于(堆)中 [cpp] view plaincopyprint? void GetMemory(char *p)   {       p = (char *)malloc(100)

anhuidafeng的专栏 516

C语言——动态内存管理

本文系统介绍了C语言动态内存管理的核心内容,包括malloc、free、calloc、realloc四大函数的使用方法、常见错误及解决方案。文章首先阐述了动态内存分配的必要性,然后详细讲解了各个函数的功能、参数和返回值,并通过代码示例演示正确用法。针对动态内存管理中易出现的6种错误(如NULL解引用、越界访问、错误释放等)进行了分析。最后通过两道经典笔试题,深入剖析了返回栈地址和内存泄漏问题,并介绍了柔性数组这一特殊数据结构。文末总结了C/C++程序的内存区域划分,为读者构建完整的动态内存管理知识体系。

Chen_LSN的博客 1017

360研发工程师笔试题解析:C/C++与系统原理核心考点

C语言指针与内存管理是研发工程师笔试中的经典考点,其背后涉及数组退化和局部变量生命周期等底层原理,直接影响系统程序的稳定性。操作系统中的死锁、进程线程与虚拟内存机制同样决定了对并发和资源调度的理解深度。而TCP协议状态机、TIME_WAIT等网络细节,则是排查网络异常的基础。这些知识构成安全软件、底层组件开发的核心技术价值,也是360等安全公司筛选人才时反复考察的内容。从基础概念到工程实践,本文基于360历年笔试题目,梳理C/C++、操作系统、网络协议及算法的高频考点与解题思路,帮助求职者针对性备考。

weixin_34226182的博客 378

c++ 面试题 面试题复盘

目录 1. #include与#include"filename.h"的区别 2 C++中的类与c中的struct的区别 3.malloc/free 与 new delete 4 类的多态.封装,继承的理解 5. 编写程序判断 bool float int 和0的关系 6 不使用c++ 或者c 的库函数编写strcopy函数的实现 7 计算sizeof 的结果 8 判断数组对象返回的函数指针,通过printf输出的结果 9 使用的STL容器有哪些,用过的其中的算法有哪些、 10 如下算法

u010029439的博客 197

C语言进阶知识--动态内存管理

本文聚焦C语言动态内存管理,针对静态内存大小固定、无法适配运行时需求的问题,系统讲解核心内容。重点介绍malloc、free、calloc、realloc四大函数的功能、参数规则与使用要点,强调返回值检查、避免野指针等关键注意事项。梳理NULL解引用、内存泄漏等6类常见错误及规避方法,分析4道经典笔试题陷阱与修复方案。详解C99柔性数组的定义、优势及使用,对比其与“结构体+指针”的差异。最后总结C/C++程序内存区域划分,明确栈区、堆区等核心区域特点,为规范动态内存使用、避免内存错误提供全面指导。

HD12345432的博客 1092

C基础--函数参数副本

转自:http://blog.csdn.net/chujiangke001/article/details/38553173 1 void GetMemory(char *p, int num) 2 { 3 p = (char*)malloc(sizeof(char)*num); 4 } 5 6 void main(void) 7 { 8...

weixin_30851409的博客 75

指针参数是如何传递内存的?

Test 函数的语句GetMemory(str, 200)并没有使str 获得期望的内存,str 依旧是NULL,为什么?void GetMemory(char *p, int num){p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(str,

---------海阔天空---------- 450

C++函数的传入参数是指针的指针(**)的详解

要修改变量的值,需要使用变量类型的指针作为参数或者变量的引用。如果变量是一般类型的变量,例如int,则需要使用int 类型的指针类型int *作为参数或者int的引用类型int&。但是如果变量类型是指针类型,例如char*,那么需要使用该类型的指针,即指向指针的指针类型 char* *,或者该类型的引用类型char*&。   首先要清楚  不管是指针还是值传入函数后都会创建一个副本,函

u011555996的博客 4027

C++内存问题(很多公司面试的题目,值得一看,看懂了别忘了告诉我)

C++内存问题(很多公司面试的题目,值得一看,看懂了别忘了告诉我) void GetMemory(char *p){p=(char*)malloc(100);}void Test(void){char *str = NULL;GetMemory(str);strcpy(str,"helloworld");printf(str);}请问运行Test函数会有什么样的结果?答:程序崩溃。因为

t0nsha's Blog 3216

C 语言(十二):动态内存管理全解析-从基础函数到柔性数组与内存分区

本文系统讲解了C语言动态内存管理的核心知识。主要内容包括:四大内存分配函数(malloc、free、calloc、realloc)的使用方法和注意事项;六种常见内存错误及避坑指南;四道经典面试题解析;C99柔性数组的特性与优势;以及C/C++程序的内存分区模型。重点强调了动态内存分配的必要性、正确使用方法和"谁申请谁释放"的核心原则,帮助开发者掌握这一关键技能,避免内存泄漏等问题。

Luminousone的博客 546

C++ 内存泄漏检测

“该死系统存在内存泄漏问题”,项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导致任何问题。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上。如果程序运行时间足够长,如后台进程运行在服务器上,只要服务器不宕机就一...

qq_32619837的博客 544

动态内存管理

动态内存管理

Bshaya_的博客 228

9.存储类别、链接、和内存管理【由浅入深.c】

本文介绍存储类别、链接、和内存管理相关内容。

插花弄玉的博客 497

面试题集合

一、360面试题 1、求一个序列的最长上升子序列(不降) 方法一:动态规划:,其中num[]数组中存放的是0~i的最长子序列长度 #include&lt;iostream&gt; #define MAX 100 using namespace std; //时间复杂度为O(n^2) int LIS(int a[], int n) { int num[MAX]; //用来存放对应点的最长...

找个特立不独行的名的博客 438
上一篇: java实现ping功能
下一篇: java中克隆,浅拷贝,神拷贝
ysh512
博客等级 码龄17年 4粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值