C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分

简介: C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分

题目一

题目描述

//请问代码的运行结果如何?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char * p)
{
  p = (char *)malloc(100);
}
void Test(void)
{
  char * str = NULL;
  GetMemory(str);
  strcpy(str,"hello world");
  printf(str);
}
int main()
{
  Test();
  return 0;
}

题目答案

什么都不打印,且存在内存泄露。

题目分析

代码改正

有两种方法改正:

一: (让GetMemory返回指针,记得释放内存)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory(char * p)
{
  p = (char *)malloc(100);
  return p;
}
void Test(void)
{
  char * str = NULL;
  str = GetMemory(str);
  strcpy(str,"hello world");
  printf(str);
  free(str);
  str = NULL;
}
int main()
{
  Test();
  return 0;
}

二:(传址)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char ** p)
{
  *p = (char *)malloc(100);
}
void Test(void)
{
  char * str = NULL;
  GetMemory(&str);
  strcpy(str,"hello world");
  printf(str);
  free(str);
  str = NULL;
}
int main()
{
  Test();
  return 0;
}

题目二

题目描述

//请问代码运行的结果如何?
#include <stdio.h>
 
char* GetMemory(void)
{
  char p[] = {"hello world"};
  return p;
}
void Test(void)
{
  char * str = NULL;
  str = GetMemory();
  printf(str);
} 
int main()
{
  Test();
  return 0;
}

题目答案

打印出随机值,并非hello world。

题目分析

GetMemory函数内部创建的数组是在栈区上的,该函数结束,p数组的空间就还给了操作系统;返回的地址是没有实际的意义的,如果通过返回的地址去访问内存,就是非法访问。

(存放在堆区的话则不会被立刻销毁)

2-1

下面的代码是否出错?

int * func (void)
{
    int * ptr;
    *ptr = 10;
    return ptr;
}

此处的ptr为野指针,没有经过初始化,使用不了。

故而该代码出错。

题目三

题目描述

//请判断代码是否出错?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);
} 
int main()
{
  Test();
  return 0;
}

题目答案

该代码错误,其忘记释放内存空间。

后加上

即可

题目四

题目描述

//请判断下面代码是否出错?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void Test(void)
{
  char * str = (char*)malloc(100);
  strcpy(str,"hello");
  free(str);
  if(str != NULL)
  {
    strcpy(str,"world");
    printf(str);
  }
} 
int main()
{
  Test();
  return 0;
}

题目答案

出错。str被释放之后还被使用。

题目分析

free函数释放完空间之后是不会帮指针赋值为空,此时再去使用它就会造成非法访问。

所以使用完free函数之后一定要把指针赋为空指针。

C/C++中程序内存区域划分

1.栈区(stack) :在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。钱内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。


2.堆区(heap) : 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统)回收。分配方式类似于链表。


3.数据段(静态区) ( static):存放全局变量、静态数据。程序结束后由系统释放。


4.代码段:存放函数体(类成员函数和全局函数)的二进制代码。


实际上普通的局部变量是在栈区分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。


但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁


所以生命周期变长。


目录
相关文章
|
10天前
|
存储 安全 程序员
|
14天前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
18 0
|
15天前
|
存储 算法 编译器
程序与技术分享:C++模板元编程简介
程序与技术分享:C++模板元编程简介
11 0
|
15天前
|
存储 JavaScript 前端开发
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
|
15天前
|
存储 编译器 C语言
C语言的联合体:一种节省内存的数据结构
C语言的联合体:一种节省内存的数据结构
13 0
|
15天前
|
自然语言处理 C语言 C++
程序与技术分享:C++写一个简单的解析器(分析C语言)
程序与技术分享:C++写一个简单的解析器(分析C语言)
|
1天前
|
算法 编译器 C语言
深入浅出C语言—【函数】下
深入浅出C语言—【函数】下
|
13天前
|
Java C语言 C++
定义C语言的int main()函数
定义C语言的int main()函数
|
16天前
|
C语言
C语言prinf函数
C语言prinf函数
13 4