Search code examples
cvisual-studio-2019dynamic-memory-allocationallocation

C allocation - why is visual studio 2019 asking me to allocate memory and codeBlocks is not?


I'm trying to learn to use Visual Code 2019. My problem is that when I run a code I get this error message, "expected constant expression" and when I run the same code in CodeBlocks the function works with no problem.

Doing a google search I learned that I need to allocate memory for this line of code monster temp[l2 + h2];

My questions are how do I malloc this line? and why is visual studio 2019 asking me to allocate memory and codeBlocks is not?

void m_s_m(monster *list, int l1, int h1, int l2, int h2, int *comparisons, int *copies, int *block_copies, int *mallocs, int use_name, int use_weight)
{
    monster temp[l2+h2];
    int index = l1;
    int k=l1;
    (*mallocs)++;
    (*block_copies)++;
    while(l1<=h1 && l2<=h2)
    {
        (*comparisons)++;
        if(use_name == 1)
        {
            if(strcmp(list[l1].name, list[l2].name)<0)
            {
                (*copies)++;
                temp[index] = list[l1];
                l1 = l1++;
            }
            else
            {
                (*copies)++;
                temp[index] = list[l2];
                l2 = l2++;
            }
        }
        if(use_weight == 1)
        {
            if(list[l1].weight<list[l2].weight)
            {
                (*copies)++;
                temp[index] = list[l1];
                l1 = l1++;
            }
            else
            {
                (*copies)++;
                temp[index] = list[l2];
                l2 = l2++;
            }
        }
        index++;
    }
    if(l1>h1)
    {
        (*block_copies)++;
        while(l2<=h2)
        {
            (*copies)++;
            (*comparisons)++;
            temp[index] = list[l2];
            index++;
            l2++;
        }
    }
    else
    {
        (*block_copies)++;
        while(l1<=h1)
        {
            (*copies)++;
            (*comparisons)++;
            temp[index] = list[l1];
            index++;
            l1++;
        }
    }
    (*block_copies)++;
    while(k<index)
    {
        (*copies)++;
        list[k]=temp[k];
        k++;
    }

}


Solution

  • There are two problems with

    monster temp[l2 + h2];
    

    First, it's a Variable-Length Array (VLA). Originally, C required you to use constant array sizes because the compiler needed to know how much memory the array was going to occupy. But in C99, by popular demand, C allowed local arrays to be declared with a size not known until the function is executed. In fact, the size could be different between one function call and the next one, which is why they're called Variable-Length. VLAs are an optional feature of C11, largely because of Microsoft's reluctance to implement them. And Microsoft never did implement them. So you can't use them with a Microsoft C compiler.

    Most other C compilers are completely OK with them, and I suppose your Code Blocks install is using some C compiler other than the Microsoft compiler. But just because you can use VLAs doesn't mean that it's a good idea. You should only allocate an array on the stack (whether it's fixed length or variable length) if you're sure that it will fit on the stack. That's tricky because you have no way of knowing how big the stack is, but it's reasonable to assume that the stack is big enough for a few shortish arrays. There's no way to even give you a guideline, but on a "desktop" operating system, you can almost certainly get away with thousands of elements. Millions of elements is asking for trouble.

    The problem with VLAs is that you really don't know how big the array is going to be. If the array declaration is a compile-time constant, someone could come by and say to you, "yeah, an array of 12 ints is fine", or "wtf, you're trying to put 100 million doubles on the stack." But with VLAs no-one knows. It's highly likely that someday you'll run the program with too large an array and it will crash or open your computer up to a hostile takeover or some such. Sorting functions tend to get called with large arrays.

    So, yeah, it's better to malloc even if the compiler doesn't force you to.

    So that's one problem. The other problem is that l2 + h2 cannot be a valid array size. I don't really know what l2 and h2 are (as I said in a comment, using variable names like that is like writing a novel where there are 20 different characters all named "Sue"), but I can guess that they are both indices into the array being sorted. And adding two indices together is a completely meaningless act. (A meaningful sum is a starting point and a length, not a starting point and an ending point.)

    So on top of temp being a VLA it's a VLA whose size hasn't been calculated correctly.