c/c++ 数组的大小

11 篇文章 1 订阅

正整形常量作为数组大小

#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;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tadus_zeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值