Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7955 Discussions

Segmentation fault for -O0 compilation

Dny
Beginner
655 Views
Hello All,

I'm running a test code using icc 11.0.074.

Following is my test code. It very sample code to sum the array element.

#include
#include
#include


#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;


sscanf(argv[1], "%ld", &size);

a=(float *) malloc (sizeof(float)* size);

if (a == NULL){
printf("\n\n ERROR: Memory Allocation not possible\n\n");
exit(-1);
}

for(i=0;i a=k;
k=(k+1)%10;
}

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

I observe that when I compiled 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.

See the output below
$ ./a.out 10000

Addition Complete, # of Element= 10000
$ ./a.out 100000
Segmentation fault

Can you please give any suggestion for this?

Thanking you,

Regards,
Dny.
0 Kudos
1 Solution
Om_S_Intel
Employee
655 Views

Themalloc() declaration in stdlib.h is as as given below:

void * malloc ( size_t size );

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

The implicit declaration will force void ponterreturned frommallocto integer, the integer is converted again to float pointer. These conversions results in improper value for returned memeory address and the application crashes.

View solution in original post

0 Kudos
6 Replies
jimdempseyatthecove
Honored Contributor III
655 Views

Try

a=(float *) malloc (sizeof(float)* (size+4));

If that fails, increase 4 to 128.

Your original code should not have failed.

If increasing the size to include padd space then this may indicate a compiler problem.
If the error persists then this may be some other problem

Just prior to allocation print out the value of size.
Following the allocation, on successful allocation, print a message indicating allocation succeeded and print the value of the pointer returned. The value may be significant (it could be junk).

Then following that print out

printf("probing a[0]n");
a[0] = 0.;
printf("probing a[%ld]n", size-1);
a[size-1] = 0.;
printf("probing succeededn");

Jim Dempsey





0 Kudos
Dny
Beginner
655 Views

Try

a=(float *) malloc (sizeof(float)* (size+4));

If that fails, increase 4 to 128.

Your original code should not have failed.

If increasing the size to include padd space then this may indicate a compiler problem.
If the error persists then this may be some other problem

Just prior to allocation print out the value of size.
Following the allocation, on successful allocation, print a message indicating allocation succeeded and print the value of the pointer returned. The value may be significant (it could be junk).

Then following that print out

printf("probing a[0]n");
a[0] = 0.;
printf("probing a[%ld]n", size-1);
a[size-1] = 0.;
printf("probing succeededn");

Jim Dempsey






Hello Sir,
Thanks for your reply,

Yes , you are right its returning me garbage pointer for allocating 100,000 elements.

As you suggested I tried increasing size by 128 but it doesn't help.

Following is my modified source code and output below it.

[cpp]#include 
#include 
#include


    #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;


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


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

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

$ 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

Can you give please give more suggestions?

Thanking you,

Regards,
Dny


0 Kudos
Om_S_Intel
Employee
655 Views

It seems malloc() isimplicitly declared. When I included "stdlib.h" header, the issue is resolved.
0 Kudos
Dny
Beginner
655 Views

It seems malloc() isimplicitly declared. When I included "stdlib.h" header, the issue is resolved.


Hello Sir,

Thanks for your reply and answer.

The issue is resolved.
Can you please explain what does "malloc() isimplicitly declared" means and why it was giving error, and how does "stdlib.h" helped?

Thanking you,

Regards,
Dny

0 Kudos
Om_S_Intel
Employee
656 Views

Themalloc() declaration in stdlib.h is as as given below:

void * malloc ( size_t size );

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

The implicit declaration will force void ponterreturned frommallocto integer, the integer is converted again to float pointer. These conversions results in improper value for returned memeory address and the application crashes.

0 Kudos
srimks
New Contributor II
655 Views

Themalloc() declaration in stdlib.h is as as given below:

void * malloc ( size_t size );

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

The implicit declaration will force void ponterreturned frommallocto integer, the integer is converted again to float pointer. These conversions results in improper value for returned memeory address and the application crashes.

Omkar very true, to confirm more plz have a look on asm as generated for -O0 -

---
movl -20(%rbp), %eax #26.7
movl %eax, -48(%rbp) #26.7
fildl -48(%rbp) #26.7
fstps -32(%rbp) #26.2
movss -32(%rbp), %xmm0 #26.2
movq -56(%rbp), %rax #26.4
movq -64(%rbp), %rdx #26.2
movss %xmm0, (%rdx,%rax,4) #26.2
movl -20(%rbp), %eax #27.5
incl %eax #27.7
movl $10, %edx #27.2
movl %edx, -40(%rbp) #27.10
cltd #27.10
movl -40(%rbp), %ecx #27.10
idivl %ecx #27.10
movl %edx, -20(%rbp) #27.2
incq -56(%rbp) #25.17
movq -56(%rbp), %rax #25.10
movq -80(%rbp), %rdx #25.12
cmpq %rdx, %rax #25.12
jl ..B1.8 # Prob 50% #25.12
---

You can also check the .S for same section for default (-O2).

Somehow, people do miss trivial things, so the issue was simply calling proper system header file.

Personally, when any things works for higher level optimization of any compilers, normally in maximum, it should also work for lower level too, which means when above code works for -O2, it should work for -O0 also as these instructions are all tested.

Jim, I think you also missed the thought process in making out the call for header file rather pointing towards Compiler as a bug.

~BR
0 Kudos
Reply