首页 > 系统相关 >C语言中的指针与内存管理:两种情况分析

C语言中的指针与内存管理:两种情况分析

时间:2024-10-15 22:44:46浏览次数:8  
标签:block modify C语言 内存 data Block 指针

在 C 语言中,指针的使用和内存管理是非常重要的概念。在本文中,我们将分析两种情况:一种是通过指针修改结构体内容,另一种是错误地尝试通过指针分配新的内存。我们将详细探讨这两种情况中的内存管理问题和如何避免常见的错误。

第一例:通过指针修改结构体内容

以下是第一段代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Block {
    char data[8];
} Block;

void modify_block(Block *block) 
{
    block->data[0] = 'b';
}

int main() 
{
    Block *block = malloc(sizeof(Block));  // 动态分配内存
    block->data[0] = 'a';                   // 初始化为 'a'
    block->data[1] = '\0';                  // 字符串结束符
    modify_block(block);                    // 通过指针传递
    printf("%s\n", block->data);            // 输出 'b'

    free(block); // 释放动态分配的内存
    return 0;
}

分析

  1. 结构体与动态分配

    • main 函数中,使用 malloc 动态分配了一个 Block 结构体的内存。这个内存块的地址被赋值给指针 block
  2. 通过指针修改内容

    • modify_block 函数中,传递了 block 的地址(即指向 Block 的指针)。函数内部直接使用这个指针来修改 data 数组的内容。
  3. 输出结果

    • 最终的输出为 b,因为通过指针成功地修改了 block->data[0] 的值。

第二例:错误的内存分配

接下来是第二段代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Block {
    char data[8];
} Block;

void modify_block(Block *block) 
{
    block = malloc(sizeof(Block)); // 试图重新分配内存
    block->data[0] = 'b';          // 修改新分配的内存
    block->data[1] = '\0';
}

int main() 
{
    Block *block = NULL;           // 初始化为空指针
    modify_block(block);           // 传递空指针
    printf("%s\n", block->data);   // 尝试输出数据

    free(block); // 释放动态分配的内存
    return 0;
}

分析

  1. 空指针传递

    • main 函数中,指针 block 被初始化为 NULL。当调用 modify_block(block) 时,实际上是传递了一个空指针。
  2. 局部修改

    • modify_block 函数中,尝试用 mallocblock 分配新的内存并修改其内容。然而,这里 block 的指向仅在 modify_block 函数内部有效,修改并不会影响 main 函数中的 block 指针。
  3. 导致错误

    • printf("%s\n", block->data); 被执行时,由于 block 仍然是 NULL,程序会尝试访问一个未分配的内存区域,导致运行时错误(通常为“段错误”)。

总结与教训

  1. 指针传递的含义

    • 在 C 语言中,所有的参数都是通过值传递的。传递指针时,传递的是指针的值(即内存地址)。因此在函数内修改指针本身(例如将其指向新的内存)不会影响原指针的值,但我们可以通过指针间接的影响它所指向的内容,从而变成 引用传递
  2. 内存管理

    • 动态分配内存时,确保正确地管理指针。如果在函数中重新分配了指针,应该通过传递指向指针的指针(Block **block)来实现。

改进后的代码

以下是改进后的代码,使用指向指针的指针来正确分配内存:

#include <stdio.h>
#include <stdlib.h>

typedef struct Block {
    char data[8];
} Block;

void modify_block(Block **block) 
{
    *block = malloc(sizeof(Block)); // 正确分配内存
    (*block)->data[0] = 'b';        // 修改新分配的内存
    (*block)->data[1] = '\0';
}

int main() 
{
    Block *block = NULL;           // 初始化为空指针
    modify_block(&block);          // 传递指向指针的指针
    printf("%s\n", block->data);   // 输出 'b'

    free(block); // 释放内存
    return 0;
}

输出结果

运行改进后的代码将输出:

b

标签:block,modify,C语言,内存,data,Block,指针
From: https://www.cnblogs.com/dylaris/p/18468678

相关文章

  • 数据结构(c语言版)-为什么想起来很简单的代码,写起来那么费劲呢?
    作为一个代码小垃圾,三行五行的基本语句都写不出来。课上,双链表的插入写起来都那么费劲,真糟糕。思路很简单,为什么代码不会写?需要对基本语句再熟悉。为什么会考虑不到保存指针(指针覆盖)的情况?因为在思考数据元素插入链表问题时,使用的是全知视角(上帝视角),“偷看答案”了。但是,对于每......
  • C语言程序设计现代方法_读书笔记
    C语言程序设计现代方法第2章C语言基本概念(P10)在C语言中,函数仅仅是一系列组合在一起并且赋予了名字的语句。(P14)一旦变量被赋值,就可以用它来辅助计算其他变量的值。(P17)C语言的一个通用原则:在任何需要数值的地方,都可以使用具有相同类型的表达式。(P19)在C语言中,标识符可......
  • 【C语言】预编译+编译+汇编+链接
    文章目录翻译环境和运行环境翻译环境预处理(预编译)编译汇编链接运行环境接下来是预处理阶段的一系列知识,认真阅读哦预定义符号#define定义常量#define定义宏带有副作用的宏参数宏替换的规则宏函数的对比#和##命名约定#undef命令行定义条件编译头文件的包含嵌套文件包含......
  • C语言——数组超详细版总结
    目录1一维数组1.1一维数组的创建与初始化1.2.1一维数组的创建1.2.2一维数组的初始化1.2一维数组的访问1.3一维数组在内存中的存储2二维数组2.1二维数组的创建与初始化2.1.1二维数组的创建2.2.2二维数组的初始化2.2二维数组的访问2.3二维数组在内存中的......
  • 双指针大总结
    1.A-B数对P1102A-B数对-洛谷题目背景出题是一件痛苦的事情!相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的A+BProblem,改用A-B了哈哈!题目描述给出一串正整数数列以及一个正整数\(C\),要求计算出所有满足\(A-B=C\)的数对的个数(不同位置的数字一样的......
  • 【C语言】动态内存管理及相关笔试题
    文章目录一、为什么有动态内存分配二、malloc和free1.malloc函数的使用2.free函数的使用三、calloc和realloc1.calloc函数的使用2.realloc函数的使用四、常见动态内存分配的错误五、动态内存经典笔试题题1题2题3六、总结C/C++中程序内存区域划分一、为什么有动态......
  • 曝iPhone 18 Pro Max首发2nm芯片:内存升级12GB
    10月15日消息,业内人士手机晶片达人爆料,2026年的iPhone18系列首发2nm处理器A20,这颗芯片采用全新的WMCM封装,内存同时升级到12GB。结合此前爆料的信息,目前可以确定顶配版iPhone18ProMax能首发A20,并配备12GB内存,至于iPhone18,按照苹果的差异化策略,有可能无缘2nm和12GB内存。作......
  • 【汇编语言】寄存器(内存访问)(二)—— DS和[address]
    前言......
  • 【C语言】sizeof
    tmp_buf=(char*)malloc(size)不可以直接使用`sizeof`来查看动态分配内存的大小。在C语言中,`sizeof`操作符是在编译时确定类型或对象的大小,并不能用于动态获取malloc分配的内存大小。下面解释为什么不能用`sizeof(tmp_buf)`查看动态分配的内存大小:1.编译时vs运行时:siz......
  • C语言学习笔记(3)
    提前批第二题:#include<stdio.h>#defineN10voidReadData(inta[],intn);voidPrintData(inta[],intn);voidMaxMinExchange(inta[],intn);voidmain(){ inta[N],n; printf("Inputn(n<=10):\n"); scanf("%d",&n); if(n>0&......