1、p 和 "hello,world"存储在内存哪个区域?
int main()
{
char *p = "hello,world";
return 0;
}
- p在栈区,因为p是一个局部变量。
- "hello,world"在只读区域(.ro段),因为"hello,world"是字符串常量
2、一个由C/C++编译的程序,会将占用的内存分为几个部分:堆、栈、代码段、数据段、BSS段。请问以下程序中的变量a、b、c、d,分别被存在内存的哪个部分?
int a = 0;
char *b;
int main()
{
int c;
static char d = 'a';
b = malloc(10);
*b = d;
return 0;
}
- a在数据段,因为a是一个已初始化的全局变量
- b在bss段,因为a是一个未初始化的全局变量
- c在栈区,c是一个局部变量
- d在代码段
3、如下代码:变量g_iA,g_iB,g_iC,iD,iE, iF, piG,iH 分别在内存中的什么区( )
int g_iA = 1;
int g_iB;
static int g_iC = 1;
void func1(){
static int iD=2;
iD++;
int iE=2;
iE++;
}
void func2(){
int iF=3;
int *piG = (int*) malloc(4);
}
int main(){
int iH = 100;
}
- g_iA 在数据段,因为g_iA是一个已初始化的全局变量
- g_iB在bss段,因为g_iB是一个未初始化的全局变量
- g_iC在数据段,因为g_iC是一个已初始化的static 全局变量
- iD在代码段
- iE在栈区,因为iE是一个局部变量
- iF在栈区,因为iF是一个局部变量
- piG在堆区,因为malloc手动分配空间
- iH在栈区,因为iF是一个局部变量
4、有关内存的思考题
void GetMemory(char *p)
{
p =(char *)malloc(100);
}
void Test(void)
{
char *str=NULL;
GetMemory(str);
strcpy(str,"hello world");
printf(str);
}
请问运行 Test 函数会有什么样的结果?
运行Test函数将会导致程序崩溃。原因是在GetMemory函数中,内存空间被分配给了p指针,但是并没有将分配的内存空间的地址传递回Test函数中的str指针。因此,str指针仍然是空指针,尝试在空指针上进行strcpy和printf操作会导致错误。
char * GetMemory(void)
{
char pl[] = "hello world"; //char *p = "hello world"
return p1;
}
Void Test(void)
{
char *str=NULL;
str = GetMemory();
printf(str);
}
请问运行 Test 函数会有什么样的结果?
运行Test函数会导致程序崩溃,因为Test函数中的printf语句尝试打印一个空指针。在GetMemory函数中,p1是一个局部变量,在函数结束后将被销毁,函数返回后str指向一个无效的内存地址。因此,在Test函数中打印str会导致程序错误。
void GetMemory(char **p,int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello world");
printf(str);
}
请问运行 Test 函数会有什么样的结果?
运行Test函数会打印出 "hello world"。
void Test (void)
{
char *str = (char *)malloc(100);
strcpy(str,"hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
请问运行 Test 函数会有什么样的结果?
运行Test函数会发生未定义的行为,可能会导致程序崩溃或产生其他不可预测的结果。虽然在调用free函数后,指针str被释放,但是在if语句中又尝试使用str指针进行操作,这是错误的。因此,我们不能假定在指针str被释放后它仍然可用,因此不能进行任何操作。
5、堆和栈的区别是什么?
- 管理分配不同:栈区是计算机自动分配和释放内存,堆区是程序员手动分配和释放内存
- 空间大小不同:栈是向低地址扩展的数据结构,是一块连续的内存区域。堆是向高地址扩展的数据结构,是不连续的内存区域。
- 是否产生碎片:对于堆来讲,频繁的malloc/free势必会造成内存空间的不连 续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题。
- 增长方向不同:堆的增长方向是向上的,即向着内存地址增加的方向;栈的增长方向是向下的,即向着内存地址减小的方向。
6、什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?
内存泄漏:如果没有适时释放被动态分配的内存,会导致内存泄露问题。未释放的内存一直占用系统资源,使得系统变慢并最终导致崩溃。
内存泄漏的解决方法:
①及时使用free()释放不再使用的内存
②合理设计数据结构和算法,避免内存无限增长
③设置合理的变量作用域,减少内存占用
指针越界的解决方法:
①使用数组时确保下标的范围,使用循环计数或条件判断控制范围
②使用指针时,进行if(NULL==p)的检查
③使用strncat 和 strncpy可以确保不会溢出目标缓冲区
strcpy(dest , src);
strncpy(dest , src , strlen(dest))