企业网站制作查询,电子商务网站开发教程课本例题,腾讯朋友圈广告投放价格,外贸网店怎么开店点击 C 语言编程核心突破 快速C语言入门 混用 C 与 C 的 calloc 和 new 导致的问题 前言一、问题代码二、使用new总结 前言
要解决问题: 同样的代码, 含有std::string的结构, 在gcc环境通过calloc可以赋值, 但是在VS下不行
想到的思路: std::string不是平凡类, 按道… 点击 C 语言编程核心突破 快速C语言入门 混用 C 与 C 的 calloc 和 new 导致的问题 前言一、问题代码二、使用new总结 前言
要解决问题: 同样的代码, 含有std::string的结构, 在gcc环境通过calloc可以赋值, 但是在VS下不行
想到的思路: std::string不是平凡类, 按道理不能通过calloc初始化, 会产生问题, 但神奇的gcc却貌似可以正常运行.
其它的补充: 混用C和C真的不是一个好的习惯, 尤其涉及内存分配问题. 一、问题代码
#include cstdlib
#include iostream
#include string#define MAX_PERSON_COUNT 3struct Person
{std::string m_name;int age;
};int main()
{std::string name;std::cin name;Person *test static_castPerson *(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 3struct Person
{std::string m_name;int age;
};int main()
{std::string name;std::cin name;Person *test new Person[MAX_PERSON_COUNT];// static_castPerson *(calloc(MAX_PERSON_COUNT, sizeof(Person)));test-m_name name;std::cout test-m_name;return 0;
}
用new就意味着, 在C中, 编译器会将结构当作类来处理, 使用默认构造函数, 那么string会被正确初始化, 无论它是如何实现的, 在任何编译器将可正确运行. 总结
混用C和C并不是一个好的习惯, 同时, 这是两种语言, 虽然绝大部分是兼容的, 但我相信, 绝大部分人无法区分, 在任意编译器下, 它们的区分究竟是什么, 这里坑恐怕不少, 如果你有试错的本钱, 可随意, 但如果没有, 还是让上帝的归上帝, 凯撒的归凯撒吧. 点击 C 语言编程核心突破 快速C语言入门