正整形常量作为数组大小
#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";
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
$ ulimit -s 10240
- 在windows下需要更改link的参数 /stack 来改变程序的默认栈大小,windows单线程默认栈大小为1MB
0 作为数组大小
- 在正常程序中,声明数组的大小必须为正整数,以下程序是不能编译成功的!!!
int main(){
int arr[0];
sizeof(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));
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);
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));
static_assert(sizeof(Str_2t) == (sizeof(char*) + sizeof(size_t)));
static_assert(sizeof(Str_3t) == (MAXBUFFSIZE + sizeof(size_t)));
return 0;
}