草庐IT

c++ - size_t 和内存分配

coder 2024-02-05 原文

有这样一个类型std::size_t。它可用于描述对象的大小,因为它保证能够表达任何对象的最大大小(所以写成 here )。但是,这是什么意思?我们实际上在内存中没有对象。那么这是否意味着这种类型可以存储一个整数,代表我们理论上可以使用的最大内存量?

如果我尝试写类似的东西

size_t maxSize = std::numeric_limits<std::size_t>::max();
new char[maxSize];

我会得到一个错误,因为数组的总大小被限制为 0x7fffffff。为什么? 此外,如果我传递一个等于 maxSize 的非常量表达式,将抛出 std::bad_array_new_length。如果我传递一个小于 maxSize 但仍大于 0x7fffffff 的表达式,将抛出 std::bad_alloc。我想 std::bad_alloc 是因为内存不足而抛出的,而不是因为大小大于 0x7fffffff。为什么会这样?我想如果我们要分配的内存大小大于 0x7fffffff(这是传递给的 const 的最大值new[] 在编译时)。为什么仅当我通过 maxSize 时才会抛出 std::bad_array_new_length?这个案例有什么特殊的吗?

顺便说一下,如果我像这样将 maxSize 传递给 vector 的构造函数:

vector<char> vec(maxSize);

std::bad_alloc 将被抛出,而不是 std::bad_array_new_length。这是否意味着 vector 使用不同的分配器?

我正在尝试自己实现数组。使用 unsigned int 来存储大小、容量和索引是一种糟糕的方法。那么像这样定义一些别名是个好主意吗:

typedef std::size_t size_type;

并使用 size_type 而不是 unsigned int

最佳答案

答案就在创建动态存储持续时间对象的过程中。

简而言之,当程序执行 new 表达式 时:new char[size]:

  1. 它会检查 s=size*sizeof(char)+x 是否为有效大小(实现定义为 0x7fffffff,这取决于 ABI)(如果您在大多数平台上 x=0创建平凡可破坏类型的数组)。如果大小无效,则抛出 bad_array_new_lenght,否则,

  2. 它调用分配函数::operator new(s)。这个函数的第一个参数是 std::size_t,这就是为什么 std::size_t 必须足够大才能创建任意大小的对象(数组是对象)。

  3. 此分配函数要求系统保留大小为 s 的存储区域。如果系统成功保留了这个空间,它会返回一个指向存储区域开头的指针。否则它会调用一个新处理程序并重试分配,但如果它再次失败,它会抛出 bad_alloc

  4. 如果分配成功,它默认初始化(在本例中)分配的size char(无操作)存储,并且它还可以将数组的大小存储在此分配的存储上(添加 x 的原因)(这在执行 delete 表达式 时使用为了知道必须调用多少析构函数。如果析构函数是微不足道的,则没有必要)。

您将在 c++ 标准中找到所有详细信息(§6.7.4 [basic.stc.dynamic]、§8.3 [expr.new]、§8.4 [expr.delete]、§21.6 [support.dynamic]) .

对于最后一个问题,您可以考虑对索引和对象大小使用有符号 类型。即使对象大小或索引不应为负数,标准也强制要求无符号算术遵循模算术,这严重限制了优化。此外,无符号整数类型的算术和比较是经常出现错误的主题。 std::size_t 出于兼容性原因是无符号的,之所以选择无符号是因为史前机器的位数很短! (16 位或更少!)

关于c++ - size_t 和内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46160622/

有关c++ - size_t 和内存分配的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  4. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  5. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  9. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  10. ruby-on-rails - 使用 Dragonfly 从 URL 分配图像 - 2

    我正在使用Dragonfly在Rails3.1应用程序上处理图像。我正在努力通过url将图像分配给模型。我有一个很好的表格:{:multipart=>true}do|f|%>RemovePicture?Dragonfly的文档指出:Dragonfly提供了一个直接从url分配的访问器:@album.cover_image_url='http://some.url/file.jpg'但是当我在控制台中尝试时:=>#ruby-1.9.2-p290>picture.image_url="http://i.imgur.com/QQiMz.jpg"=>"http://i.imgur.com/QQ

随机推荐