Memory allocation results in segmentation violation


Problem : 

I observe that when I compiled the following test case using default flag, its working properly. When I disabled optimization using flag -O0, it working for array size 10000, but unfortunately its giving segmentation fault error for size 100000.

$ cat mytest1.c
// mytest1.c

#include <sys/time.h>
#include <time.h>
#include<stdio.h>

#define SIZE 1024 // Size = 1G
int main(int argc, char *argv[])
{
     float *a; //DB Init

     long i,size=0,j;
     float sum=0;
     int k=0;
     int return_value;


     sscanf(argv[1], "%ld", &size);
     printf("\n Size before Allocation = %ld\n",size);
     a=(float *) malloc (sizeof(float)* (size+128));

     printf("Value of return from malloc = %d",return_value);

     if (a == NULL){
         printf("\n\n ERROR: Memory Allocation not possible\n\n");
         exit(-1);
     }
     else
     {
         printf("Value of return pointer after memory allocation = %ld",a);
         printf("\n\n probing a[0]\n");
         a[0] = 0.;
         printf("probing a[%ld]\n", size-1);
         a[size-1] = 0.;
         printf("probing succeeded\n");
         return 0;
    }

    for(i=0;i< size; i++){
        sum+=a[i];
    }
    printf("\n Addition Complete, # of Element= %ld\n", size);
    free((void *)a);
    return 0;
}


$ icc -O0 mytest1.c
$ ./a.out 100000

Size before Allocation = 100000
Value of return pointer after memory allocation = -1788305392

probing a[0]
Segmentation fault

$ icc mytest1.c
$ ./a.out 100000

Size before Allocation = 100000
Value of return pointer after memory allocation = 182895288336

probing a[0]
probing a[99999]
probing succeeded


Environment : 

Intel C++ compiler, Linux x86_64

Root Cause : 

Implicitly declared malloc() returns improper address pointer and the application crashes. The compiler must know the function signature to handle it properly.

Resolution : 

Implicitly declared malloc() returns improper address pointer. The malloc() declaration in stdlib.h is as given below:

void * malloc ( size_t size );

The compiler must know the function signature to handle it properly. If we do not provide declaration to compiler, the compiler assumes that the value returned by the function is integer. This is called implicit declaration.

The implicit declaration will force void pointer returned from malloc() to integer, the integer is converted again to float pointer. These conversions results in improper value for returned memory address and the application crashes.

For more complete information about compiler optimizations, see our Optimization Notice.