正整形常量作为数组大小
#include <iostream>
#include <cassert>
#define MAXLEN 2048
const static size_t kMaxLen = 2048
int main(){
char arr0[2048];
char arr1[MAXLEN];
char arr2[kMaxLen];
static_assert(sizeof(arr0) == 2048);
static_assert(sizeof(arr1) == 2048);
static_assert(sizeof(arr2) == 2048);
return 0;
}
正整形变量作为数组大小
- 在C89之前,数组的长度必须是常量,之后的标准里可以使用变量来作为数组的长度,并且占用的是栈空间,并且sizeof可以推断出数组变量的大小。
#include <cassert>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
bool find_in(const std::string &s, const std::vector<std::string> &l) {
for (const auto &m : l) {
if (s.find(m) != s.npos) {
return true;
}
}
return false;
}
int main(int argc, char *argv[]) {
assert(argc >= 2);
int arr_size = atoi(argv[1]);
int arr[arr_size];
std::cout << "arr sizeof:" << (sizeof(arr)) << std::endl;
bzero(arr, sizeof(int) * arr_size);
const char *self_status = "/proc/self/status"; // linux 系统下查看自己进程的状态 也可以是 /proc/{processId}/status
std::ifstream ifs(self_status);
std::string line_;
while (std::getline(ifs, line_)) {
if (find_in(line_, {"VmSize:" ,// 进程所占的总空间
"VmRSS:" , // 进程所占的物理空间
"VmData:", // 堆空间
"VmStk:", // 栈空间
"VmExe:", // 代码空间
"VmLib:" // 库所占的空间
})) {
std::cout << line_ << std::endl;
}
}
return 0;
}
- 数组可以得到的大小不是无限,受栈空间限制,linux下通过 ulimit 查看和修改 进程的栈空间限制
$ ulimit -a # 查看所有
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63068
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63068
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
$ ulimit -s
8192 # 默认8M
$ ulimit -s 10240 # 也可以 ulimit -s unlimited ,不过不建议
- 在windows下需要更改link的参数 /stack 来改变程序的默认栈大小,windows单线程默认栈大小为1MB
0 作为数组大小
- 在正常程序中,声明数组的大小必须为正整数,以下程序是不能编译成功的!!!
int main(){
int arr[0]; // error 不能分配常量大小为 0 的数组
sizeof(arr); // error “arr”: 未知的大小
(void*)arr;
return 0;
}
- 在类或结构体的最后一个成员变量可以使用,且该类或结构体不可被继承。
#include <iostream>
#pragma pack(1)
struct MString final {
size_t length;
char data[0];
};
MString* make_str(const char* const s){
size_t length = strlen(s);
MString *res = (MString*)malloc(sizeof(MString) + length);
res->length = length;
memcpy(res->data,s,length);
return res;
}
void release_str(MString* ms){
free(ms);
}
int main(){
static_assert(sizeof(MString) == sizeof(size_t)); // data不占用空间
MString* ms = make_str("Hello world!");
unsigned long m_ptr = (unsigned long)ms;
unsigned long d_ptr = (unsigned long)(ms->data);
assert(m_ptr + sizeof(MString) == d_ptr); // data代表了ms尾部地址
release_str(ms);
return 0;
}
- 这样写有什么好处?
对比以下就明白了
const static size_t MAXBUFFSIZE = 1024;
#pragma pack(1)
struct Str_1t {
size_t length;
char data[0];
};
struct Str_2t{
char* data;
size_t length;
};
struct Str_3t{
size_t length;
char data[MAXBUFFSIZE];
}
int main(){
static_assert(sizeof(Str_1t) == sizeof(size_t)); // Str_1t 的sizeof最小
static_assert(sizeof(Str_2t) == (sizeof(char*) + sizeof(size_t)));
static_assert(sizeof(Str_3t) == (MAXBUFFSIZE + sizeof(size_t)));
return 0;
}
版权声明:本文为weixin_43868793原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。