C - Cannot take input after allocating dynamic array [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
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.

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.

Related

Odd C global char type declaration error message in both GCC and Clang?

Question: Is it me, or do both GCC and Clang have not quite correct error messages when assessing particular global char declarations in C?
---And a particular note regarding a similar question is that I'm looking for clarification regarding why the char declaration is getting this reaction. There are related questions, yes, but all I saw there was int declarations.
$ gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0
$ clang --version
clang version 10.0.0-4ubuntu1
Consider the following C code, able.c:
#include <stdio.h>
char able;
able = 'X';
int main(void)
{
printf("%c", able);
}
A first note is that yes, combining the declaration and the initialization of able is much more efficient. However, when run through GCC and Clang, the error messages that turn up seem to me to be, basically, incorrect messages:
$ clang -Weverything able.c
able.c:5:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
able = 'X';
^
able.c:5:1: error: redefinition of 'able' with a different type: 'int' vs 'char'
able.c:3:6: note: previous definition is here
char able;
^
able.c:3:6: warning: no previous extern declaration for non-static variable 'able' [-Wmissing-variable-declarations]
char able;
^
able.c:3:1: note: declare 'static' if the variable is not intended to be used outside of this translation unit
char able;
^
2 warnings and 1 error generated.
$ gcc -Wall -Wextra -Wpedantic able.c
able.c:5:1: warning: data definition has no type or storage class
5 | able = 'X';
| ^~~~
able.c:5:1: warning: type defaults to ‘int’ in declaration of ‘able’ [-Wimplicit-int]
able.c:5:1: error: conflicting types for ‘able’
able.c:3:6: note: previous declaration of ‘able’ was here
3 | char able;
| ^~~~
Both sets of messages complain about a missing type specifier, except that the type specifier---char---is indeed right there. When the declaration and initialization messages are combined in that spot, above/before the main function, the program compiles. When the pair of messages are placed in the main function, even without being combined, the program also compiles.
So the char able; statement is perfectly fine, so why those error messages?
You can't do
char able;
able='X';
on file scope.
You can only do it in one line, not split, like you are used in functions.
The C compiler thinks:
char able; //Declare a variable of type char with name able.
able = 'X'; //Assign the ASCII-value of 'X' to a variable called able of type `int`.
The int is implicit because of backwards compatibility with really old versions. (Because of this you will sometimes see main() instead of int main(void)).
Furthermore, you have now two variables of the same name. This leads to this error:
redefinition of 'able' with a different type: 'int' vs 'char'
Edit:
Here an excerpt from the C specification (Draft):
Annex A, A.1 (Lexical grammar), A.2.4 (External Definition)
translation-unit: //Essentially a file
external-declaration
translation-unit external-declaration
external-declaration:
function-definition
declaration //The interesting one
declaration: //A 2.2 (Declarations)
declaration-specifiers init-declarator-list[opt];//init-declarator-list is optional
static_assert-declaration//Not interesting here
declaration-specifiers:
storage-class-specifier declaration-specifiers[opt]
type-specifier declaration-specifiers[opt]
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiers[opt]
alignment-specifier declaration-specifiers[opt]
As you can see here in the grammar, there is no place on translationunit-base for only an assignment.
The compile gives error as able='X' is never executed by the program. (C program acts sequentially inside the functions only. For global variables only the declaration with/without initialization is considered.
#include <stdio.h>
char able;
able = 'X'; //This statement is never executed
int main(void)
{
printf("%c", able);
}
A similar question can be found at: Why can't I assign values to global variables outside a function in C?
As statements are not allowed in file scope the compiler tries to interpret this statement
able = 'X';
as a declaration. But it does not find a type specifier. So it issues the message
able.c:5:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
able = 'X';
After it inserted the default type specifier int it sees that the name able is declared twice like
char able;
int able = 'X';
where int is the type specifier inserted by the compiler by default.
So the compiler issues the message
able.c:5:1: error: redefinition of 'able' with a different type: 'int' vs 'char'
able.c:3:6: note: previous definition is here
char able;
^
Inside block scope you may place declarations and statements. So this code snippet
char able;
able = 'X';
placed in a function block scope will compile successfully.
From the C Standard (6.8 Statements and blocks)
3 A block allows a set of declarations and statements to be grouped
into one syntactic unit.
able = 'X';
You cant have any code or assignments outside the functions. compiler treats it as new definitions with implicit int type. The assignment has to be in the function body as in the example.
#include <stdio.h>
char able;
void foo()
{
able = 'X';
}
int main(void)
{
foo();
printf("%c", able);
}
https://godbolt.org/z/dea7q7

mathgl and single letter variable names in C

I am trying to implement MATHGL graphs in QT windows.
Compilation of the appropriate libraries went fine, and example provided compiles and runs without error.
When trying to build sample code, something strange happens when I try to add a single letter named variable regardless of its type (int, double, others).
This simple code illustrates the problem
#include <mgl2/mgl_cf.h>
int sample(HMGL gr, void *p)
{
int I; /* REMOVE THIS LINE OR RENAME VARIABLE (TWO LETTERS) FOR COMPILATION */
mgl_rotate(gr,40.,60.,0.);
mgl_box(gr);
return 0;
}
int main(int argc,char **argv)
{
HMGL gr;
gr = mgl_create_graph_qt(sample,"MathGL examples",0,0);
return mgl_qt_run();
}
MATHGL version is 2.1.3.1, compiler is gcc 4.7.2, libraries used: -lpng15 -lz -lm -lstdc++ -lmgl -lmgl-qt
Error in compilation reads:
file.c: In function ‘sample’:
file.c:5:7: error: expected identifier or ‘(’ before ‘__extension__’
file.c: In function ‘main’:
file.c:16:6: warning: assignment makes pointer from integer without a cast [enabled by default]
I do not know what I'm missing here, can you please help me??
thanks in advance!!
Your problem: I is most likely a macro for the imaginary unit (as described here).
Use a different variable name (and avoid all-caps variable names in general).

c - warning: implicit declaration of function ‘printf’

I know alot of similar questions were asked before but i couldn't find something that would fix this warning i get:
MyIntFunctions.c:19:2: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
Occurs here:
void IntPrint (const void *key)
{
printf("%d", *(int*)key); // line 19
printf("\t-->\t");
}
and a similar warning:
MyStringFunctions.c:22:2: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
void StringPrint (const void *key)
{
printf("%s",(char*)key); //line 22
printf("\t-->\t");
}
I really want to understand what is wrong so i won't do that again in the future.
You need to include the appropriate header
#include <stdio.h>
If you're not sure which header a standard function is defined in, the function's man page will state this.
You need to include a declaration of the printf() function.
#include <stdio.h>
the warning or error of kind IMPLICIT DECLARATION is that the compiler is expecting a Function Declaration/Prototype..
It might either be a header file or your own function Declaration..
warning: incompatible implicit declaration of built-in function 'printf'
warning: incompatible implicit declaration of built-in function 'scanf'
the above warnings of compiler says that there is need to include declaration of printf and scanf i.e. include appropriate header
#include <stdio.h>

Absurd compilation

This is a basic C code, which according to me should have thrown three errors (function not defined, function not returning anything, function argument missing). But to my surprise it threw nothing, it compiled and gave some garbage results:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a=f1();
printf("a %d\n",a);
system("PAUSE");
return 0;
}
f1(int *t)
{
printf("t %d", t);
}
PS: I am using a gcc compiler on windows.
In C when a function is not declared is is assumed to return int and compilation continues (btw this can lead to nasty bugs). If the function is declared without a type (as f1() is in your code it is assumed to return int. Not returning a value from a non-void function (as in your code) is undefined behavior.
So none of the points you mention are required to cause a compilation error. Undefined behavior is not required to prevent your program from running - the program might run and might even produce good looking results.
Firstly, you were not compiling with warnings enabled. You should usually invoke gcc with at least the -Wall switch - for your example code, that gives:
x.c: In function 'main':
x.c:7: warning: implicit declaration of function 'f1'
x.c: At top level:
x.c:15: warning: return type defaults to 'int'
x.c: In function 'f1':
x.c:16: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
x.c:17: warning: control reaches end of non-void function
Secondly, the reason that it compiles is that all of the errors in it are of a form called "undefined behaviour", which means that the compiler isn't required to diagnose them and stop compilation - it can simply produce garbage results.
You would probably be happier if you used gcc's -Wall option to enable all warnings. Then you would see this while compiling:
C:\test>make
gcc -Wall prog.c -o prog
prog.c: In function 'main':
prog.c:7:5: warning: implicit declaration of function 'f1'
prog.c: At top level:
prog.c:14:1: warning: return type defaults to 'int'
prog.c: In function 'f1':
prog.c:16:8: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
prog.c:17:1: warning: control reaches end of non-void function
You can also use -Werror to turn all warnings in to errors (so you are forced to fix them).
Try compiling again with the -Wall flag. That turns on all warnings, then you'll see plenty:
c.c: In function ‘main’:
c.c:7: warning: implicit declaration of function ‘f1’
c.c: At top level:
c.c:15: warning: return type defaults to ‘int’
c.c: In function ‘f1’:
c.c:16: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
c.c:17: warning: control reaches end of non-void function
Since you don't have any compile time errors, just warnings, the code compiles fine. It just won't execute very well.
f1 is considered to have the implicit prototype 'int f1(int)'.
Hence the call is valid.
f1 does not return anything whereas it is implicitly suppoed to return an int: the behaviour is undefined.
The compiler could warn you that the implicit prototype does not agree with the definition. It could also ask for a proper return. This is part of the checks that the static analysis inside the compiler could perform: gcc does not do it, others may.
In any case compilers usually do not guarantee anything about non ISO conforming programs.
If you add -Wall to your gcc commands you should get some warnings. I guess it works as old style C had loose function prototyping. And will assume unknown functions return int. The linker worked because there were no undefined symbols (f1 exists) but you got garbage as what was passed on the stack (i.e. nothing) was not what was expected.

"Implicit declaration" warning

For this code:
int i=0; char **mainp;
for(i=0;i<2;++i)
{
mainp[i]=malloc(sizeof(char)*200);
if(!scanf("%[^#],#",mainp[i]))
break;
if(i<2)
scanf("%[^#],#",mainp[i]);
}
GCC emits the warnings:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
warning: ‘mainp’ may be used uninitialized in this function
And I get a segmentation fault at runtime
input:(P>Q),(Q>R),-R#-P
output:
(P>Q),(Q>R),-R
(empt slot)
i expected to give me
(P>Q),(Q>R),-R
-P //where should i fix in my code such that it gives me expected
//output
Problem #1:
warning: ‘mainp’ may be used uninitialized in this function
You need to allocate memory for the array of arrays first.
char **mainp = malloc(sizeof(char*)*2);
Problem #2:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
You need to include stdio.h at the top of your file:
#include <stdio.h>
Problem #3: (Not included in your compiling warnings)
Remember to free both the allocated array members and also the array of array address.
gcc expects this line at the beginning of your file:
#include <stdio.h>
and a declaration of mainp like this one:
char *mainp[2];
You shouldn't use functions without declaring them; you used scanf, but at no point in your code is scanf declared. Since it's a standard library function it's declared in one of the standard headers, stdio.h, so you just need to include it:
#include <stdio.h>
Brian's answer is good for the other part

Resources