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修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁


所以生命周期变长。


目录
相关文章
|
1天前
|
存储 Linux C语言
c++进阶篇——初窥多线程(二) 基于C语言实现的多线程编写
本文介绍了C++中使用C语言的pthread库实现多线程编程。`pthread_create`用于创建新线程,`pthread_self`返回当前线程ID。示例展示了如何创建线程并打印线程ID,强调了线程同步的重要性,如使用`sleep`防止主线程提前结束导致子线程未执行完。`pthread_exit`用于线程退出,`pthread_join`用来等待并回收子线程,`pthread_detach`则分离线程。文中还提到了线程取消功能,通过`pthread_cancel`实现。这些基本操作是理解和使用C/C++多线程的关键。
|
3天前
|
监控 算法 Java
Java虚拟机(JVM)使用多种垃圾回收算法来管理内存,以确保程序运行时不会因为内存不足而崩溃。
【6月更文挑战第20天】Java JVM运用多种GC算法,如标记-清除、复制、标记-压缩、分代收集、增量收集、并行收集和并发标记,以自动化内存管理,防止因内存耗尽导致的程序崩溃。这些算法各有优劣,适应不同的性能和资源需求。垃圾回收旨在避免手动内存管理,简化编程。当遇到内存泄漏,可以借助VisualVM、JConsole或MAT等工具监测内存、生成堆转储,分析引用链并定位泄漏源,从而解决问题。
12 4
|
3天前
|
编译器
程序的内存模型\栈区
程序的内存模型\栈区
15 4
|
3天前
|
C语言 C++
程序的内存模型\全局区
程序的内存模型\全局区
7 2
|
8天前
|
程序员 C语言 C++
【C语言基础】:动态内存管理(含经典笔试题分析)-2
【C语言基础】:动态内存管理(含经典笔试题分析)
|
8天前
|
程序员 编译器 C语言
【C语言基础】:动态内存管理(含经典笔试题分析)-1
【C语言基础】:动态内存管理(含经典笔试题分析)
|
1天前
|
存储 C语言
C语言----数据在内存中的存储(2)
C语言----数据在内存中的存储
|
1天前
|
存储 C语言
C语言----数据在内存中的存储(1)
C语言----数据在内存中的存储
|
1天前
|
C语言 C++
C语言----C语言内存函数
C语言----C语言内存函数
|
1天前
|
存储 C语言
C语言---求一个整数存储在内存中的二进制中1的个数--3种方法
C语言---求一个整数存储在内存中的二进制中1的个数--3种方法