3

this is my code:

void foo(int num) {
    int *pArr = (int *)malloc(num * sizeof(int));
    // allocate array of 'sale' structs for each region
    for (int i = 0; pArr != NULL && i < num; i++) {
        pArr[i] = 1;
    }
}

int main() {
    int num = 36;
    foo(num);
}

The expression pArr[i] = 1; gives a C6386 warning

Warning C6386 Buffer overrun while writing to 'pArr': the writable size is 'num*sizeof(int)' bytes, but '8' bytes might be written.

This is very weird since the number of iterations of the for loop, AND the size of the array in the head are both dependant on num so an overrun can't actually occur ever.

And then there is a detailed explanation:

i may equal 1
pArr may be NULL (Continue this loop)
Invalid write to pArr, (outside its writable range)

But of course this is a visual studio mistake, pArr cannot be NULL, as this is a condition for entering the loop.

How can I clean this warning?
Thank you all

chqrlie
  • 131,814
  • 10
  • 121
  • 189

2 Answers2

3

There is a simple change you can make to no longer get the C6386 warning. You should test the value of num before attempting the allocation. The C language standard has an interesting statement about passing a size of 0 to malloc().

7.22.3 Memory management functions

If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned to indicate an error, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

The POSIX standard says something similar:

If size is 0, either:

A null pointer shall be returned and errno may be set to an implementation-defined value, or

A pointer to the allocated space shall be returned. The application shall ensure that the pointer is not used to access an object.

Microsoft's Code Analysis doesn't emit a C6386 for this code:

void foo(int num)
{
    if (num == 0) { // avoid passing 0 to malloc()
        return;
    }
    int *pArr = (int *) malloc(num * sizeof(int));
    // allocate array of 'sale' structs for each region
    for (int i = 0; pArr != NULL && i < num; i++) {
        pArr[i] = 1;
    }
}
Blastfurnace
  • 18,411
  • 56
  • 55
  • 70
0

The problem occurs because VS seems to be unable to deduce that the loop will never run if pArr is NULL. Replacing your code with

void foo(int num) {
    int *pArr = (int *)malloc(num * sizeof(int));
    
    if (pArr == NULL) {
        return;
    }
    
    // allocate array of 'sale' structs for each region
    for (int i = 0; i < num; i++) {
        pArr[i] = 1;
    }
}

int main() {
    int num = 36;
    foo(num);
}

will solve your problem and be more runtime-efficient.

Xaver
  • 1,035
  • 9
  • 17