当前位置: 首页 > article >正文

C语言,无法正常释放char*的空间

问题描述

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

const int STRSIZR = 10;

int main()
{
    char *str = (char *)malloc(STRSIZR*sizeof(char));
    str = "string";
    printf("%s\n", str);
    free(str);
}

乍一看,这块代码没有什么问题。直接书写时vscode也没有进行报错,可运行后便会弹出错误:

free(): invalid pointer

问题原因

开启断点调试

在第一次分配空间之后,str指针指向分配好的地址 0x5555555592a0

再执行一步,

此时str指针指向了地址 0x555555556008,此处为字符串"string"的存放地址,即text 区域(也称为代码段)

造成两个问题

  1. 释放代码段区域的空间必然导致错误(错误诱发原因)
  2. 原有分配的内存空间丢失

或许这也是使用g++编译时提示ISO禁止将string转化为char*的原因之一

问题解决

#include <stdio.h>
#include <stdio.h>
#include <string.h>

const int STRSIZR = 10;

int main()
{
    char *str = (char *)malloc(STRSIZR*sizeof(char));
    memset(str,0,STRSIZR*sizeof(char));
    strcat(str,"string");
    printf("%s\n", str);
    free(str);
}

拓展-结构体中的char*

#include <stdio.h>
#include <stdio.h>
#include <string.h>

const int STRSIZR = 10;

typedef struct node
{
    int index;
    char *name;
} Node;

int main()
{
    char *str = (char *)malloc(STRSIZR*sizeof(char));
    memset(str,0,STRSIZR*sizeof(char));

    Node *n = (Node *)malloc(sizeof(Node));
    memset(n, 0, sizeof(Node));


    n->name=str;
    printf("%s\n", n->name);
    free(n);
}

考虑以上代码,运行后不报错。可真的没有问题吗?

未必,仍然考虑内存管理。使用valgrind帮我们一探究竟

valgrind --leak-check=full ./program

是的,当我们释放Node的时候,其实只是释放了char* name这个指针(8个字节)的这块空间。而并不会将其对应的分配内存空间释放。

#include <stdio.h>
#include <stdio.h>
#include <string.h>

const int STRSIZR = 10;

typedef struct node
{
    int index;
    char *name;
} Node;

int main()
{
    char *str = (char *)malloc(STRSIZR*sizeof(char));
    memset(str,0,STRSIZR*sizeof(char));

    Node *n = (Node *)malloc(sizeof(Node));
    memset(n, 0, sizeof(Node));


    n->name=str;
    printf("%s\n", n->name);
    free(n->name);
    free(n);
}

先释放内部的char*,再释放整个结构体!


http://www.kler.cn/a/521517.html

相关文章:

  • 14-8C++STL的queue容器
  • HttpClient学习
  • 快速分析LabVIEW主要特征进行判断
  • NLP模型大对比:Transformer > RNN > n-gram
  • 用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南
  • 2025春晚刘谦魔术揭秘魔术过程
  • 03-画P封装(制作2D+添加3D)
  • 《剪映5.9官方安装包》免费自动生成字幕
  • PHP根据IP地址获取地理位置城市和经纬度信息
  • flink StreamGraph解析
  • 为何SAP S4系统中要设置MRP区域?MD04中可否同时显示工厂级、库存地点级的数据?
  • Hive:内部表和外部表,内外转换
  • 企业微信开发009_使用WxJava企业微信开发框架_封装第三方应用企业微信开发002_并且实现多企业授权访问---企业微信开发011
  • C#实现SQL Server数据血缘关系生成程序
  • C++初阶—string类
  • MS10-087 挂马漏洞复现
  • FastExcel使用详解
  • three.js+WebGL踩坑经验合集(5.1):THREE.Line2又一坑:镜像后不见了
  • jEasyUI 创建复杂布局
  • 【知识科普】HTTP相关内容说明
  • JavaWeb 学习笔记 XML 和 Json 篇 | 020
  • 单片机基础模块学习——PCF8591芯片
  • Mac m1,m2,m3芯片使用nvm安装node14报错
  • Excel制作合同到期自动提醒!
  • ESP32服务器和PC客户端的Wi-Fi通信
  • 海浪波高预测(背景调研)