-2

I am struggling with strange result for basic program.

I checked tutorialspoint site and it says unsigned long is 8byte. unsigned long range

I am multiplying unsigned long and unsigned int. enter image description here

And it seems that multiplying result does not exceeds the maximum value of unsigned long(18,446,744,073,709,551,615). But I get 56557 instead of 85,899,402,477.

I tried also

unsigned long gridTotalSize = (unsigned long)xGrids * yGrids;

but the same result.

I wanted to limit the memory allocation capacity by this multiplying value.

unsigned long gridTotalSize = ((unsigned long )xGrids) * yGrids;
if (gridTotalSize == 1)
{
    return false;
}
else if (gridTotalSize > 1000000)
{
    return false;
}

But because gridTotalSize = 56557, it passes this size limit check, and tries to allocate 85,899,402,477 bytes, this is nearly 85GB, and very frustrating. Every time I debug, I should press power off button and restart computer for completely stuck from memory overflow.

std::vector<Row> rows;
rows.resize(yGrids); //111,321
for (Row& row : rows)
{
    row.resize(xGrids); //771,637
}

I am wasting so many time for this. Any help will be really appreciated.

Denis Turgenev
  • 138
  • 1
  • 9
  • 2
    `because gridTotalSize = 56557, it passes this size limit check, and tries to allocate 85,899,402,477 bytes` how are you checking that? How do you know what is the value of a variable? `But I get 56557 instead of 85,899,402,477.` Where and how do you "get it"? `and tries to allocate` Where does it "try to allocate"? Please post an [MCVE]. – KamilCuk Jun 21 '21 at 07:49
  • 1
    On my PC (64b), `unsigned long` is 4B. I need to use `unsigned long long` to get 8B. The standard doesn't specify the size precisely. – Damien Jun 21 '21 at 07:49
  • I am using 64bit computer, 64 bit OS. – Denis Turgenev Jun 21 '21 at 07:50
  • 10
    That site is wrong. The size of `long` is platform dependent. Even on 64 bit OS it may be only 32 bits. – interjay Jun 21 '21 at 07:50
  • I thought tutorialspoint is famous site, so absolutely trusted it. But now, i'll check again. thanks – Denis Turgenev Jun 21 '21 at 07:51
  • 6
    https://en.cppreference.com/w/cpp/language/types. When a tutorial claims that the size of unisnged long is exactly 8bytes, dont use that tutorial – 463035818_is_not_an_ai Jun 21 '21 at 07:52
  • 4
    @DenisTurgenev Windows has 4 byte `long`s, even with the 64bit version. If you need a 8byte variable ==> `uint64_t`. – mch Jun 21 '21 at 07:52
  • @KamilCuk, I already added allocate code. std::vector rows; rows.resize(yGrids); //111,321 for (Row& row : rows) { row.resize(xGrids); //771,637 } I could check breakpoint here – Denis Turgenev Jun 21 '21 at 07:52
  • Sorry, @KamilCuk, yes, I have to allocate 2D grid with cells (xGrids * yGrids). If cell count exceeds 100000, then I am going to show error message, if not, I'll allocate (xGrids * yGrids) cells. and for my case, cell count 85,000,000,000 but the cell limit check didn't work. sorry again for my poor situation explain. – Denis Turgenev Jun 21 '21 at 07:57
  • 1
    any books or websites that say C++ types have a fixed width are shitty and should be thrown away. See [What does the C++ standard state the size of int, long type to be?](https://stackoverflow.com/q/589575/995714) – phuclv Jun 21 '21 at 08:02
  • Have you checked the size of unsigned long and sizeof unsigned long long on your system? If you really have done what you describe, the only explanation is that they are only 4 bytes... and that can't be true... – Support Ukraine Jun 21 '21 at 08:04
  • A simple test: `printf("%zu\n", sizeof(unsigned)); printf("%zu\n", sizeof(unsigned long)); printf("%zu\n", sizeof(unsigned long long));` What does it print? – Support Ukraine Jun 21 '21 at 08:05
  • Then, assuming that `yGrids = 111321, xGrids = 771637` then `gridTotalSize = ((unsigned long long)xGrids) * yGrids;` should have worked. [Can't reproduce](https://godbolt.org/z/W5Ejqz83o). – KamilCuk Jun 21 '21 at 08:05
  • @DenisTurgenev There are several famous C++ tutorial sites, but not a single one of them is trustworthy. – molbdnilo Jun 21 '21 at 08:07
  • 2
    See https://ideone.com/UL8nlH Copy the code and run it on your own system – Support Ukraine Jun 21 '21 at 08:09
  • 2
    Don't trust that site. Here is another rant about it: https://stackoverflow.com/a/55731680/6699433 – klutt Jun 21 '21 at 08:12
  • Also don't post images of code. Post the code! Your image doesn't show the type of the operands used in the multiplication. Further it doesn't show any cast/conversion to unsigned long before the multiplication. If the operands are 4 byte types (e.g. unsigned) then the result will also just be 4 bytes. I have a feeling that your actual code is different from what you tell us... – Support Ukraine Jun 21 '21 at 08:13
  • 1
    soudn like a job for `uint64_t` – Ivan Jun 21 '21 at 08:28
  • 1
    Why are you using the C tag? Your code is clearly C++. – klutt Jun 21 '21 at 08:33
  • @4386427, thanks it turns out be sizeof (unsigned long) = 4 – Denis Turgenev Jun 21 '21 at 08:46
  • 2
    @DenisTurgenev "I thought tutorialspoint is famous site" It's an _infamous_ site and we at SO are pretty tired of cleaning up their mess. See for example this: [Are the “C mock tests” at tutorialspoint correct?](https://stackoverflow.com/q/62816217/584518) Admittedly bit of a rant, but it would seem that the people who write the articles at their site are kind of beginners themselves and definitely don't use proof-reading/peer review. Any C book will be of higher quality, since publishers generally enforce some manner of proof reading by experts. – Lundin Jun 21 '21 at 08:47
  • @Lundin, thank you for giving me how to choose learning material. yes, I'll be away from tutorialspoint. I loved it, because it has covered nearly all fields of programming. – Denis Turgenev Jun 21 '21 at 08:49
  • @Ivan, uint64_t seems to be a clean solution for avoiding annoying long, long long problems. I upvote you. – Denis Turgenev Jun 21 '21 at 08:50
  • @DenisTurgenev And how about `sizeof(unsigned long long)` ? Also just 4 bytes? – Support Ukraine Jun 21 '21 at 08:55
  • This is another question but related for my case. Is there any way to limit the dynamic allocated capacity in visual studio 2019 project settings? to avoid computer stuck for coder's mistake. It's serious to reboot computer every time. – Denis Turgenev Jun 21 '21 at 08:55
  • @4386427, it's 8. that's working now with unsigned long long, and uint64_t seems to be a more clean solution. Thank you. – Denis Turgenev Jun 21 '21 at 08:56
  • @DenisTurgenev I don't get it... In your question you tell us that you already tried: `unsigned long long gridTotalSize = ((unsigned long long)xGrids) * yGrids;` And that should have worked! – Support Ukraine Jun 21 '21 at 08:57
  • sorry but I said tried with unsigned long. :) check again. – Denis Turgenev Jun 21 '21 at 08:58
  • What I said is ->. instead of unsigned long gridTotalSize = xGrids * yGrids; here xGrids and yGrids are unsigned int type as you can see in variable watch dock widget. tried unsigned long gridTotalSize = (unsigned long)xGrids * yGrids; – Denis Turgenev Jun 21 '21 at 09:00
  • @DenisTurgenev But in your quest you write `unsigned long long gridTotalSize = ((unsigned long long)xGrids) * yGrids;` !? This is very confusing... Did you or didn't you use that code!? If not you should edit the question – Support Ukraine Jun 21 '21 at 09:03
  • @4386427, really, sorry, I was pasting from many trying projects and yes, it was my fault. I should have to paste unsigned long gridTotalSize = ((unsigned long)xGrids) * yGrids; – Denis Turgenev Jun 21 '21 at 09:08
  • @4386427 ;) if you're interested, Any idea on https://stackoverflow.com/questions/68067280/how-to-get-resizeevent-already-executed-qdialog? – Denis Turgenev Jun 21 '21 at 12:13
  • @DenisTurgenev Unfortunately I don't know much about qt/OpenGL so can't help this time. – Support Ukraine Jun 21 '21 at 12:30

1 Answers1

3

The width of unsigned long depends on the C or C++ implementation. The C standard and the C++ standard only require it to be at least 32 bits.

To calculate sizes of objects, include <stddef.h> in C or <cstddef> in C++ and use the size_t type in C or std::size_t in C++. It is intended to be a type suitable for working with sizes. (Although the C standard does not explicitly guarantee this. The C++ standard might not either.)

To print a size_t value with printf, use %zu. In C++, it can of course be inserted into a stream in the usual way.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 2
    @4386427: While the title of the question asks how to get an exact result for `unsigned long` multiplication, the body of the question makes it clear OP IS actually trying to calculate sizes of objects and should be using the correct type for that. That may be a wider type, which would solve their problem immediately. If they still have an overflow (wrapping) problem, that can be addressed as a new question (which is likely a duplicate). – Eric Postpischil Jun 21 '21 at 09:03
  • sorry, @4386427, I voted, and canceled vote, and voted again as long as you agree. And as long as only one answer(i mean not chat, sorry for my english), I give him upvote. don't you mind? If you post your answer, I would up vote you ;) – Denis Turgenev Jun 21 '21 at 09:11
  • @DenisTurgenev No, I don't mind at all. If this answer helped you it's actually good that you accept it and upvote it. Fine. To me it was just confusing how/why it helped you but that's my problem - not yours :-) – Support Ukraine Jun 21 '21 at 09:14
  • @4386427 you 're cool man!! I expect talk to you often, here in stack overflow. – Denis Turgenev Jun 21 '21 at 09:15
  • Oh, no @EricPostpischil, printf("%d\n", sizeof(std::size_t)); this prints 4. not 8. What I was wrong? I included #include Now I understand why 4386427 has confused. – Denis Turgenev Jun 21 '21 at 09:18
  • I tried %zu as @EricPostpischil told, but the same, print 4 – Denis Turgenev Jun 21 '21 at 09:25
  • Sorry, I was hurry and was creating x86 project. yes, 8 right. Today I am out of soul. Making others tired. – Denis Turgenev Jun 21 '21 at 09:26