Path: csiph.com!news.swapon.de!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: recovering from std::bad_alloc in std::string reserve Date: Thu, 27 May 2021 15:58:46 -0700 Organization: None to speak of Lines: 65 Message-ID: <87o8cvzsux.fsf@nosuchdomain.example.com> References: <_CUrI.452334$ST2.205157@fx47.iad> <87sg27zu0i.fsf@nosuchdomain.example.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="1458d77179aa98232e45e826606b1dc8"; logging-data="16992"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1824Ya4f01RE/gyVlL+7cJX" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cancel-Lock: sha1:sw81xLiNAt+++H4nPkp3HCej4U0= sha1:ulixGMDbZQRBnzaEbv9FCLaNVm4= Xref: csiph.com comp.lang.c++:79810 Keith Thompson writes: > scott@slp53.sl.home (Scott Lurndal) writes: >> Lynn McGuire writes: >>>On 5/27/2021 12:50 AM, Christian Gollwitzer wrote: >>>> Am 26.05.21 um 20:32 schrieb Lynn McGuire: - Alf >>>>> >>>>> I have already replaced the fell code with _ftelli64. >>>>> >>>>> //  get the size of the output file >>>>> fseek (pOutputFile, 0, SEEK_END); >>>>> __int64 outputFileLength = _ftelli64 (pOutputFile) + 42;  // give it >>>>> some slop >>>>> int outputFileLengthInt = (int) outputFileLength; >>>> >>>> ...and here you restrict it to 2GB again, or worse, retrieve a negative >>>> file size for sizes between 2GB and 4GB. >>>> >>>> >>>> To prepare for a 64bit move, you should replace all size variables with >>>> size_t for unsigned or ptrdiff_t for signed. That will correspond to a >>>> 32bit integer in 32 bit and a 64 bit integer in 64 bit. >>>> >>>>     Christian >>> >>>Done. With checking against SIZE_MAX before casting the variable to size_t. >> >> Why? size_t is guaranteed to hold the size of any object, which implies that >> it must be large enough to accomodate an object the size of the virtual address >> space. Generally it's minimum size in bits is the same as long. > > That's likely to be true, but it's not absolutely guaranteed. My apologies, I was wrong. > size_t is intended to hold the size of any single object, but it may > not be able to hold the sum of sizes of all objects or the size of > the virtual address space. An implementation might restrict the > size of any single object to something smaller than the size of > the entire virtual address space. (Think segments.) I believe this is still correct. > Also, I haven't found anything in the standard that says you > can't at least try to create an object bigger than SIZE_MAX bytes. > calloc(SIZE_MAX, 2) attempts to allocate such an object, and I don't > see a requirement that it must fail. If an implementation lets you > define a named object bigger than SIZE_MAX bytes, then presumably > applying sizeof to it would result in an overflow, and therefore > undefined behavior. > > Any reasonable implementation will simply make size_t big enough > to hold the size of any object it can create, but I don't see a > requirement for it. The above is correct in C, but not in C++, which makes an additional guarantee that C doesn't. C++17 21.2.4 [support.types.layout] says: The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object (8.3.3). -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */