gcc/g++的编译链接原理及注意事项
LINUX下默认搜索头文件及库文件的路径
编译连接
多个文件编译在linux下编译,下面有三个文件,分别是1.cpp 和 2.cpp 和myhead.h 文件。
1.cpp
1 |
|
2.cpp
1 |
|
myhead.h
1 |
|
假如他们都在一个目录下面,那么编译流程:
1 | g++ -c 2.cpp #将2.cpp 编译成2.o 文件 |
or1
2
3g++ -c 2.cpp
g++ -c 1.cpp
g++ 1.o 2.o -o test
重写C++中异常类的what方法
待补充完善:错误原因以及为什么这么修改
坑源
在实现项目ZeroTensor的专属异常类时,需要实现exception
类的what
方法。
出现问题及解决办法
首先需要看一下exception
基类中关于what
方法的原始定义:
1 |
下面是正确的重写方式
1 | const char *what() const throw() override { return error_msg_.c_str(); } |
如果去掉throw() , 则会报错:
1 | looser throw specifier for ‘virtual const char* zerotensor::ZerotensorError::what() const’ |
如果将char * 改为 string,则会报错:
1 | error: ‘const string zerotensor::ZerotensorError::what() const’ cannot be overloaded |
声明模板类对象,报错“undefined reference to”
坑源
实现ZeroTensor项目中的Shape3D
类时,为了可以处理多种类型的数据(int,double等),需要使用模板类
出现问题和解决办法
在实现的时候将模板类的声明和定义写在的不同位置,编译时报错:1
undefined reference to XXXX
这是因为模板类并不是普通的类和成员函数!它们只是说明了如何生成类和成员函数定义。因此,不能将模板成员函数放在独立的实现文件中。
由于模板不是函数,因此它们不能单独编译。模板必须与特定的模板实例化请求一起使用。为此,最简单的方法是将所有模板信息放在一个头文件中,并在要使用这些模板的文件中包含该头文件!
还有另一种解决办法就是在stack.h
文件的末尾加上#include stack.cpp
,并在stack.cpp
文件中去掉对应的包含语句。
string.substr
坑源: leetcode, 第140题, Word Brak II
s.substr(word.size())
可以通过, 但是s.substr(0, word.size())
报错 runtime error
.
原因:1
basic_string substr(size_type pos=0, size_type count=npos) const;
当只指定一个参数时, 该参数表示的是 pos
的位置, 而 count
则默认会是字符串中剩余字符的数量.
如果 pos
的值大于字符串的size, 则会报运行时错误(runtime error
).
vector数据的内存分配问题
首先,要知道,程序所拥有的栈资源是及其有限的(Linux下用ulimit -a
或者ulimit -s
可查当前栈的大小。 因此在写程序时,绝对不能肆意使用占空间,否则就会报出Segmentation fault
。
在用vector实现三维数据时,以下的代码就会产生段错误
1 |
|
以上出现段错误的原因在于申请了过多的vecotr,导致占空间不够用,从而出现段错误,现在来看以下vector在内存中具体是如何存储的,首先看一下以下三种方式的声明:
1 |
|
假设T
是一个类型或者一个定义好的类,则以上三种情况的内存分配情况如下:
- 对于
std::vector<T> vec
;vec
在栈上(stack),而其中的元素T
保存在堆上(heap); - 对于
std::vector<T>* Vec = new std::vector<T>()
;vec
和其中的元素T
都保存在堆上; - 对于
std::vector<T*> vec
;vec
在栈上(stack),而其中的元素T
保存在堆上(heap);和第一种情况类似。
存储在栈上的元素,往往无需手动管理内存空间,通常会自动释放,而在堆上的空间,则需要手动管理。
在实现项目ZeroTensor的专属异常类时,需要实现exception
类的what
方法。
出现问题及解决办法
首先需要看一下exception
基类中关于what
方法的原始定义:
1 |
下面是正确的重写方式
1 | const char *what() const throw() override { return error_msg_.c_str(); } |
如果去掉throw() , 则会报错:
1 | looser throw specifier for ‘virtual const char* zerotensor::ZerotensorError::what() const’ |
如果将char * 改为 string,则会报错:
1 | error: ‘const string zerotensor::ZerotensorError::what() const’ cannot be overloaded |