question on unsigned int and size_t

I know to some extent size_t and unsigned int are interchangable but size_t sometimes is preferable since it is more portable. But in the following simple test code, size_t does not work and I cannot figure out why.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    size_t numOfElements;
    int *ptr;

    printf("Enter the number of elements: ");
    scanf("%d", &numOfElements);

    // dynamically allocating memory
    ptr = (int *) malloc(numOfElements * sizeof(int));
    // check if allocation is successful
    if (NULL == ptr) {
        puts("Out of Memory. Program terminated.");
        return 1;
    }

    return 0;


In the above code, no matter what value I entered, it always shows "Out of Memory. Program terminated."

In line 6, if I change size_t to unsigned int, then the memory can be successfully allocated.

Could some one give me some explanations? Thanks!
Last edited on
It works for me (when I compile it as C++). As far as I know, size_t is a C++ member, why (and how) are you using it in C? If you wanted to do the same thing in C++, you would do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <stdexcept>

int main() {
    size_t numOfElements;
    int* ptr = nullptr;

    std::cout << "Enter the number of elements: ";
    std::cin >> numOfElements;

    try {
        ptr = new int[numOfElements];
    } catch (const std::bad_alloc& ba) {
        std::cout << "Couldn't allocate memory: " << ba.what() << "\n";
        return 1;
    }

    return 0;
}


I don't know why I just did that, its obvious you are using C...
Anyway, I don't know what it is that is going on there. I'm pretty sure that size_t isn't part of C, so that might be what is going on for you.
@NT3

Thanks for your reply.

I checked Wiki, it is said "The C language provides the separate types size_t and ptrdiff_t to represent memory-related quantities." So I think size_t is part of C.

Simply converting my C code to C++ will run successfully. So my gut feeling is the use of size_t in a C program, as you mentioned. In C++, using size_t seems okay.

I normally use for(size_t i = 0; i != 10; ++i) this type of coding and it (seems) works fine. Should I change to something like for(unsigned int i = 0; i != 10; ++i)? At least in C programming?
Last edited on
For printing out a size_t, we can always just widen it to a uintmax_t

For scanf() of size_t, most compilers support "%zu". (Microsoft does not.)

1
2
3
size_t numOfElements;
scanf( "%zu", &numOfElements ) ;
printf( "numOfElements: %" PRIuMAX "\n", (uintmax_t)numOfElements ) ;


Portable scanf() for size_t is messy. I suppose something like this could be done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <inttypes.h>

const char* SCN_SIZE_T()
{
    switch ( sizeof(size_t) )
    {
        case sizeof(uint16_t) : return "%" SCNu16 "u";
        case sizeof(uint32_t) : return "%" SCNu32 "u" ;
        case sizeof(uint64_t) : return "%" SCNu64 "u" ;
        default: return "%u" ;
    }
}

int main()
{
    size_t numOfElements;
    scanf( SCN_SIZE_T(), &numOfElements ) ;
    printf( "numOfElements: %" PRIuMAX "\n", (uintmax_t)numOfElements ) ;
}

http://coliru.stacked-crooked.com/a/03bb658ede1badda
Hi,

The != in your for loop could cause trouble if you are not careful, the normal idiom is:

for(size_t i = 0; i < 10; ++i)

Also, you could attract compiler warnings if you don't use size_t along with functions that expect it.

The maximum for unsigned int is probably a smaller quantity than the max size_t, so this might cause problems too.
Topic archived. No new replies allowed.