Access violation on try to fill dynamic array (large number of items)

427 views Asked by At

I have the following C code:

int dimension; 
double *AtS;
...
AtS=(double*)malloc(sizeof(double)*dimension); 

for (i=0; i<dimension; i++)
{
  AtS[i]=0.0; 
}

While dimension is ~6-8 millions it works fine, but when it about 300 millions it fails with access violation. The following message in debug:

Unhandled exception at 0x012f1077 in mathpro.exe: 0xC0000005: Access violation writing location 0x00000000.

The same situation if I use memset() instead of cycle.

Are there any ideas how it's resolve this problem?

2

There are 2 answers

0
Captain Giraffe On BEST ANSWER

"Access violation writing location 0x00000000" is explained by the manual

http://man7.org/linux/man-pages/man3/malloc.3.html#RETURN_VALUE

On error, these functions return NULL.

Or if you prefer http://www.cplusplus.com/reference/cstdlib/malloc/.

Return Value

On success, a pointer to the memory block allocated by the function. The type of this pointer is always void*, which can be cast to the desired type of data pointer in order to be dereferenceable. If the function failed to allocate the requested block of memory, a null pointer is returned.

You have encountered an error. Quite likely out of memory.

If you were to inspect the value sizeof(double)*dimension prior to passing it to malloc, you'll find that it is indeed quite a large number.

0
Sourav Ghosh On

As already explained by Mr. Captain Giraffe in the answer that you're facing the issue because the memory allocation through malloc() has failed (quite likely for very large allocation request) and you did not check for the success of malloc() before using the returned pointer.

In case of failure. malloc() will return NULL and without a check, you'll be dereferencing a NULL pointer, which in turn invokes undefined behaviour.

Along with that, I would like to add three more points, e.g.,

  1. Please do not cast the return value of malloc() and family in C.

  2. You need not use a loop to initialize the (properly) allocated memory to 0. Rather, to get this done in an efficient manner, use either

    • you can use calloc(), which returns the memory set to zero.
    • you can use malloc() and then memset() to set the allocated memory to the particular value supplied with memset().
  3. The robust way to use malloc() in an expression is to write the expression as

    AtS=malloc(dimension * sizeof*AtS);   //sizeof is an operator
    

    which is independent to the type of AtS. At a later point, if the type of AtS is changed, you don't need to modify this expression at all.