0

I need someone to tell me what I am doing wrong over here.

void main(void) {
    int *arr,n,i;

    printf("Enter the number of elements you want to enter=");
    scanf("%d",&n);

    arr = (int*)calloc(n,sizeof(int));

    if(!arr)
        return;

    for(i=0;i<n;i++)
        scanf("%d",&arr[i]);

    for(i=0;i<n;i++)
        printf("%d ",arr[i]);

    free(arr);
}

This is nothing but a simple program to input the number of items in an array then take the input and print the inputted values. But whenever I go to input the values in the array after taking the number of items from the user, my program CRASHES. I don't understand what I am doing wrong over here. Need some help immediately. Please run the program and see if it also crashes on other systems. I executed the program using an online compiler and strangely there it was running fine. I am using the Visual Studio 2013 command line compiler to execute my program.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
Sreyan
  • 357
  • 2
  • 12
  • 5
    Have you got `#include ` above your main? – Tom Fenech Apr 17 '14 at 16:22
  • 3
    [Works perfectly fine on ideone](http://ideone.com/vWlHwM) – Sergey Kalinichenko Apr 17 '14 at 16:24
  • works fine. program doesn't crash in GCC – LearningC Apr 17 '14 at 16:25
  • i ran it on my system (codeblocks) , works fine – Aseem Goyal Apr 17 '14 at 16:25
  • This isn't actually a dynamic array, it is a static array who's size you specify at runtime. Dynamic arrays grow and shrinks based on number of values inserted. – stmfunk Apr 17 '14 at 16:27
  • @Tom Fenech: Works fine after including stdlib.h, but can you tell me how the program compiles without stdlib.h in the first place ? I mean if there is no function prototype for calloc inside stdio.h then how can the program compile fine and crash at runtime ??? Very Weird. – Sreyan Apr 17 '14 at 16:45
  • I have added to my answer so that it hopefully explains why you see no error at compile time but the code doesn't function as expected. I don't think that this question should be closed; the problem _can_ be reproduced, it is just system-dependent. – Tom Fenech Apr 19 '14 at 13:52
  • Bookmark this question so we can link to it next time someone objects to the "don't cast malloc" advice – M.M Apr 21 '14 at 10:21

1 Answers1

1

Compiling this piece of code with gcc I get:

calloc.c: In function ‘main’:
calloc.c:4:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
calloc.c:5:5: warning: incompatible implicit declaration of built-in function ‘scanf’ [enabled by default]
calloc.c:7:17: warning: incompatible implicit declaration of built-in function ‘calloc’ [enabled by default]
calloc.c:18:5: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]

using clang:

calloc.c:1:1: error: 'main' must return 'int'
void main(void) {
^
calloc.c:4:5: warning: implicitly declaring C library function 'printf' with type 'int (const char *, ...)'
    printf("Enter the number of elements you want to enter=");
    ^
calloc.c:4:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'printf'
calloc.c:5:5: warning: implicitly declaring C library function 'scanf' with type 'int (const char *, ...)'
    scanf("%d",&n);
    ^
calloc.c:5:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'scanf'
calloc.c:7:17: warning: implicitly declaring C library function 'calloc' with type 'void *(unsigned long, unsigned long)'
    arr = (int*)calloc(n,sizeof(int));
                ^
calloc.c:7:17: note: please include the header <stdlib.h> or explicitly provide a declaration for 'calloc'
calloc.c:18:5: warning: implicit declaration of function 'free' is invalid in C99 [-Wimplicit-function-declaration]
    free(arr);
    ^
4 warnings and 1 error generated.

As clang kindly pointed out, you need to add

#include <stdlib.h>
#include <stdio.h>

to the top of your code, as you are using functions that are declared within them. The functions you are using are in the standard C library, so the code will still compile but you should expect the unexpected. The reason your program crashes is likely to be that the compiler has made an incorrect assumption about the return type of calloc, as it doesn't have the correct declaration. Many systems will let you get away with this but at the very least they should warn you.

On a side note, please see this discussion on casting the return value of malloc (don't cast it). This advice also applies to calloc.


edit

Here's a minimal example which might shed some light on the issue:

a.c

#include <stdio.h>

int main()
{
    printf("%f\n", f());
    return 0;
}

b.c

float f()
{
    return 4.2;
}

These two files can be compiled separately into object files:

gcc -c a.c      # creates a.o
gcc -c b.c      # creates b.o

No warnings or errors are generated. Switching to C99 mode causes an "implicit function declaration" warning. Note that at compile-time, the function definition isn't needed. These two object files can be linked:

gcc a.o b.o

Now, the linker finds the definitions of the functions so there is no error but it is already too late. The implicit declaration of f() when a.c was compiled causes the output to be incorrect when the program is run (I get 0.000000).

The same thing has happened here as in your question. The function calloc can be found, so there is no error at link-time. However, an incorrect assumption is made about the type that it returns, so it doesn't behave as expected on your system.

Community
  • 1
  • 1
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • I got absolutely no warnings when I compiled via **cl** of Visual Studio that's why it seems so strange. I don't understand why the compiler even allows compilation when it does not have the prototypes present ? The normal rule is whenever we use a function its prototype must be declared. Is that rule relaxed when it comes to Standard C Library functions ? – Sreyan Apr 17 '14 at 17:51
  • @Sreyan You don't have to declare a prototype, it's just that one will be assumed if you don't. See [this question](http://stackoverflow.com/q/9182763/2088135) for further discussion on why you can compile without an error. I'm very surprised you don't see any warning whatsoever... – Tom Fenech Apr 18 '14 at 09:37
  • If the function call can be found then the return type can also be found. Then why does the compiler make a wrong assumption about the return type ? I mean when the compiler is compiling a.c it has to find the function f() in b.c otherwise it will give a compilation error, now since it has found the function it can easily see the return type is float. So why make an assumption about the return type in the first place ? – Sreyan Apr 20 '14 at 13:28
  • @Sreyan I have edited again so that the files are compiled separately. Hopefully, this further explains what has happened. – Tom Fenech Apr 21 '14 at 10:07
  • Thanks Tom Fenech. Your explanation is very clear. – Sreyan Apr 24 '14 at 14:50