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

2024-02-04 混用 C 与 C++ 的 calloc 和 new 导致的问题


点击 <C 语言编程核心突破> 快速C语言入门


混用 C 与 C++ 的 calloc 和 new 导致的问题

  • 前言
  • 一、问题代码
  • 二、使用new
  • 总结


前言

要解决问题: 同样的代码, 含有std::string的结构, 在gcc环境通过calloc可以赋值, 但是在VS下不行

想到的思路: std::string不是平凡类, 按道理不能通过calloc初始化, 会产生问题, 但神奇的gcc却貌似可以正常运行.

其它的补充: 混用CC++真的不是一个好的习惯, 尤其涉及内存分配问题.


一、问题代码

#include <cstdlib>
#include <iostream>
#include <string>

#define MAX_PERSON_COUNT 3

struct Person
{
    std::string m_name;
    int age;
};

int main()
{
    std::string name;
    std::cin >> name;

    Person *test =
        static_cast<Person *>(calloc(MAX_PERSON_COUNT, sizeof(Person)));

    test->m_name = name;

    std::cout << test->m_name;

    return 0;
}

struct Person中有一个std::string, 在C++中, 这是一个需要初始化的元素, 但是calloc不能调用构造函数, 只会分配一块内存, 且内存中的数据都是0.

然而神奇的是, 在gcc环境下, 可以给没有初始化的string赋值,

我们简单分析一下, 如果string的构造是一个指向字符串的指针, 以及一个代表字符长度的整型值,

那么在进行赋值的时候, 会重新开辟一块内存, 并将其地址传递给string内部的指针, 并将字符串拷贝过去

同时, 记录长度的值也传递给字符串的记录长度值的成员变量.

但为了保证性能, 可能string在初始化时默认分配一个足够大的空间, 处理小字符串,

如果在赋值时, 长度未超过这个范围, 直接拷贝字符串到内存中,

那此时calloc不能初始化的string在赋值时, 就有了隐患.

而我们不能保证string的具体实现, 所以, 用calloc分配带有非平凡类的string也就不能保证是否可用.

二、使用new

#include <cstdlib>
#include <iostream>
#include <string>

#define MAX_PERSON_COUNT 3

struct Person
{
    std::string m_name;
    int age;
};

int main()
{
    std::string name;
    std::cin >> name;

    Person *test = new Person[MAX_PERSON_COUNT];
    //       static_cast<Person *>(calloc(MAX_PERSON_COUNT, sizeof(Person)));

    test->m_name = name;

    std::cout << test->m_name;

    return 0;
}

new就意味着, 在C++中, 编译器会将结构当作类来处理, 使用默认构造函数, 那么string会被正确初始化, 无论它是如何实现的, 在任何编译器将可正确运行.


总结

混用CC++并不是一个好的习惯, 同时, 这是两种语言, 虽然绝大部分是兼容的, 但我相信, 绝大部分人无法区分, 在任意编译器下, 它们的区分究竟是什么, 这里坑恐怕不少, 如果你有试错的本钱, 可随意, 但如果没有, 还是让上帝的归上帝, 凯撒的归凯撒吧.


点击 <C 语言编程核心突破> 快速C语言入门



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

相关文章:

  • 【初阶数据结构篇】队列的实现(赋源码)
  • 大学作业:城市PM2.5预测分析数据挖掘大作业资源源码免费下载
  • 数据库-Derby
  • IDEA2023 SpringBoot整合Web开发(二)
  • 20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况
  • Visual Studio 圈复杂度评估
  • Vscode SSH使用云服务器访问内网主机
  • 10个简单有效的编辑PDF文件工具分享
  • Camunda流程引擎数据库架构
  • Dockerfile里的ENTRYPOINT和CMD
  • 如何写一个其他人可以使用的GitHub Action
  • 基于全连接神经网络模型的手写数字识别
  • JAVA组合模式详解
  • Leetcode 21:合并两个有序链表
  • 算法学习——LeetCode力扣链表篇1
  • AWS配置内网EC2服务器上网【图形化配置】
  • jsPDF+html2canvas实现html转pdf下载+打印
  • npm_config_xxx
  • 信息隐藏研究新动向
  • 使用easyExcel 定义表头 字体 格式 颜色等,定义表内容,合计
  • 标注工具体积3D数据集
  • 力扣题目训练(7)
  • 2024.2.7
  • kafka 文件存储机制
  • ComfyUI 学习笔记
  • 如何部署基于 Pyramid 的 Python WSGI Web 应用程序