The compiler shows a warning from this code [duplicate] - c

My compiler (clang) shows this message:
11:17:warning: format specifies type 'char *' but the argument has
type 'char (*)[0]' [-Wformat]
scanf("%s", &name);
~~ ^~~~~
1 warning generated.
from the following code (greetings program):
/*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[0];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", &name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
What is actually going on, and how can I fix it?

In order to understand this, you have to understand what scanf is doing. scanf in this case is reading a string from stdin, and placing it into a buffer that you give it. It does not allocate that space for you, or detect overflow. You need to allocate sufficient space for your string. As it stands now, you are allocating zero space for your string, so everything is an overflow. This is a major bug.
Say instead of char[0], you did char[40], as another user suggests.What if the user of your program writes more than 40 characters? This results in undefined behavior. Essentially, it will write to memory you don't want it to write to. It might cause a segfault, it might result in crucial memory getting overwritten, or it might happen to work. This is a weakness of scanf. Look into fgets. You tell it the size of your buffer, and input will be truncated to fit.
Of course, that has nothing to do with your warning. You're getting a warning because referring to the name of an array is the same as referring to a pointer to its first element, i.e. name <==> &(name[0]). Taking a pointer to this is like taking a pointer to a pointer, i.e. &name <==> &&(name[0]). Since scanf is looking for an argument of type char*, and it's getting a pointer to that, the type checker complains.

Your code exhibits "undefined behavior." This means anything could happen. Anything.
You are passing a zero-length array to scanf(). Also, you are not passing the array length in the format string. This results in a buffer overflow vulnerability (always, in the case of a zero-length target array).
You need something like this:
char name[51];
scanf("%50s", name);
Note the %50s now specifies the size of the target array (less one, to leave room for the null terminator!), which avoids buffer overflow. You still need to check the return value of scanf(), and whether the input name is actually too long (you wouldn't want to truncate the user's input without telling them).
If you're on Linux, check out the tool called valgrind. It is a runtime memory error detector (among other things), and can sometimes catch errors like this for you (and much less obvious ones, which is the main point). It's indispensable for many C programmers.

Just change this:
scanf("%s", &name);
to:
scanf("%39s", name);
and this:
char name[0];
to:
char name[40];
Also to you have to end it with a '\0' with:
name[39] = '\0';

Depending on how robust you want this to be you will want to reconsider the approach. I guess the first thing is whether you understand the type you are using when declaring char name[ 0 ]. this is a 'zero-sized' array of byte-sized characters. This is a confusing thing and it wouldn't surprise me if its behaviour differs across compilers...
The actual warning being complained by the compiler is that the type doesn't match. If you take the address of the first character in the array you can get rid of that (i.e. use &( name[ 0 ] ) in the scanf call). The address of name is its location on the stack - it just so happens that the array implementation uses that same location to store the array data, and name is treated differently by the compiler when used on its own so that the address of an array is the same as the address of its first element...
Using char name[ 0 ] leaves you open to causing memory corruption because there is nowhere for the string to be read, and implementation details may just luck out and allow this to work. One simple way to fix this is to replace 0 with a meaningful number which you take to the maximum length of the input string. Say 32 so that you have char name[ 32 ] instead... however this doesn't handle the case of an even longer string.
Since we live in a world of lots of memory and large stacks you can probably do char name[ 4096 ] and use 4KB of memory for the buffer and that will be absolutely fine for real world usage.
Now... if you want to be a little anal and handle pathological cases, like a user leaning on some keys whilst asleep for hours before pressing enter and adding some enormous 8000 character long string there are a few ways to handle that too with 'dynamic memory allocation', but that might be a bit beyond the scope of this answer.
As an aside, from what I understand char foo[ 0 ] is intentionally valid - it may have originated as a hack and has a confusing type, but is not uncommonly relied on for an old trick to create variable sized structs as described in this page from the GCC online docs

char name[0]; ---> char name[100];
/* You need to allocate some memory to store the name */
2.scanf("%s", &name);----> scanf("%s", name);
/* scanf takes char* as an argument so you need to pass string name only. */
i don't think that scanf("%(length - 1)s", name); is needed.
Because %s is used to reads a string. This will stop on the first whitespace character reached, or at the specified field width (e.g. "%39s"), whichever comes first.
except these don't tend to be used as often. You, of course, may use them as often as you wish!
/
*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[100];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}

Because the correct way is
scanf("%s", name);
/* ^ no ampersand
and what is
char name[0];
you should specify a non-zero length and use it for scanf length specifier
scanf("%(length - 1)s", name);
/* ^ sunstitite with the value */

there were several problems with the OPs posted code
the following fixes most of them
I includd comments to indicate where the problems are
int main ()
{
//char name[0]; // this did not allow any room for the name
char name[100] = {'\0'}; // declare a 100 byte buffer and init to all '\0'
printf("-------------------\n");
printf("Write your name:, max 99 char \n"); // 99 allows room for nul termination byte
printf("-------------------\n");
//scanf("%s", &name); // this has no limit on length of input string so can overrun buffer
if( 1 == scanf("%99s", name) ) // 1) always check returned value from I/O functions
// 2) no '&' before 'name' because
// arrays degrade to pointer to array when variable
// name is used
// 3) placed max size limit on format conversion string
// so input buffer 'name' cannot be overflowed
{ // then scanf failed
perror( "scanf failed for name" );
return(-1); // indicate error
}
// implied else, scanf successful
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
return(0); // indicate success
} // end function: main

You are reading a "string", thus the correct way is:
scanf("%s", name);
Why does the compiler complain? When you provide an argument in scanf, you provide the memory location of the variable. For example:
int x;
scanf("%d", &x);
&x is int *, i.e., a pointer to an integer, so x will get the correct value.
When you read a string, you're actually reading many char variables together. To store them, you need a char * array; well, name is char * on its own, so no need to write &name. The latter is char **, i.e., a 2-dimensional array of char.
By the way, you also need to allocate space for the characters to read. Thus, you have to write char name[20] (or any other number). You also need to provide a return 0; in your int main().

Related

Storing a string in char pointer (using scanf)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s1;
char *s2;
printf("Enter the string : ");
scanf("%s",s1);
printf("Enter the string : ");
scanf("%s",s2);
return 0;
}
I'm facing problems in taking inputs in char pointer. Here I'm just taking 1 word as input but Scanf isn't taking any inputs at all when using char pointer, but works well with char arrays. Is it a code blocks bug?
A pointer is a variable that holds a memory address.
An uninitialized variable contains (generally) some random garbage number.
When you pass some random garbage number to scanf and tell it to store a string at that address, it's no surprise that (usually) the program crashes.
It makes no sense to tell scanf to store a string at an address where you don't know what the address is. It's like telling your friend to come over to your house and when they ask which house is yours, you click somewhere random on Google Maps. It's probably going to be in the middle of the ocean or something and they'll drown.
What you need to do is make a space to put the string (such as by declaring an array) and then tell scanf to put the string in that space that you specifically made to hold the string.
A pointer to a string does not hold the string. A pointer to a string is just a signpost saying "the string is over there --->", and you can change it if you want it to point to a different place, maybe holding a different string, but it's never going to hold a string itself.
This is a beginner-C-programmers' bug as old as the language itself.
There are two good solutions to your problem, either change the definitions of s1 and s2 to something like
char s1[BUFFER_LENGTH];
char s2[BUFFER_LENGTH];
...where BUFFER_LENGTH-1 is some sufficiently long string length, to tell the compiler to allocate enough memory on the stack, or manually allocate memory in the heap for them using malloc() like so:
char *s1 = malloc(BUFFER_LENGTH);
char *s2 = malloc(BUFFER_LENGTH);
But keep in mind that in both cases your code is unsafe because for any finite-length buffer, there is a string too long for it, which can cause your program to crash or overwrite something important in memory or give hackers access to stuff etc. etc.
A safe solution is to allocate memory for your strings in one of the two above ways, and only read strings that are small enough to fit into them. If you require the program to be able to handle a string of any length, your code will be much more complex, but there's still a safe way to do it.
#include <stdio.h>
#define BUFFER_LENGTH 20 //Arbitrary max string length + 1
int main(){
char s1[BUFFER_LENGTH]; //Can safely hold 19 chars for string and a null terminator
char s2[BUFFER_LENGTH];
printf("Enter the string : ");
scanf("%19s",s1); //%19s tells the function to only read max 19 characters
printf("Enter the string : ");
scanf("%19s",s2);
{
In the above example a string longer than 19 characters will be truncated, for instance "012345678901234567890" will be stored in s1 as "0123456789012345678" and s2 will have "90" since scanf will just use the leftover characters in the input buffer for the next call.

I have problem in string, in using the gets function, in c language

I have a problem with string in the c language
we know, the string is known as a null-terminated character** array, in the string, we declare how many characters this string is store. and the memory of the character is 1byte. when we declare char name[5]; it means the string store at least 4 characters value and null value.
but there is a problem withstrong text the gets function it.
when we have entered a name that contains more than 5 characters it is accepted and prints all characters. In this case, the compiler does not throw the warning.
Please tell me the solution to it.......
the code is below.
#include<stdio.h>
int main()
{
char name[4]="smti prajapati";
printf("Print the name througth the initilizing : ");
puts(name);
printf("Enter the name : ");
gets(name);
printf("Print the name througth the user : ");
puts(name);
return 0;
}
In the terminal program trow the look like this error
rough.c: In function 'main':
rough.c:5:18: ***warning: initializer-string for array of chars is too long***
char name[1]="smti prajapati";
^~~~~~~~~~~~~~~~
Print the name througth the initilizing : s3
Enter the name : smit prajapati
Print the name througth the user : smit prajapati
You’ve declared the name array to have a single element; it’s not large enough to hold the contents of the string "smti prajapati". You’d need to declare name to be at least 15 elements wide - 14 characters in the string plus the zero terminator.
You can omit the size in the declaration and write
char name[] = "smti prajapati";
and the array size will be taken from the size of the initializer.
Note that the size of name is fixed after it is defined, and will not able to store strings longer than the initializer.
Do not use gets; if you enter a string that’s too long for the array, it will write those extra characters to whatever follows the array. This is known as a buffer overflow, and can lead to anything from corrupted data, a runtime error, or branching to a random location in your program. Buffer overflows are a common malware exploit. Use fgets instead, as it allows you to limit how many characters get written to the target.
The declaration and assignment:
char name[1] = "smti prajapati";
Can never work because you assign a string with 14 characters plus the null byte to a char array that only has space for 1 character.
The reason why you don't get errors or warnings with some ill-formed code can be explained by leeway given by C to the programmer, compilers are not mandated to issue warnings due to some types of ill-formed code like your own, this falls in the category of undefined behavior, and it's up to the programmer to avoid it.
You could use:
char name[] = "smti prajapati";
This way the size of the array will be deduced when initialized.
Or if you want to explicitly use a size:
char name[15] = "smti prajapati";
Note that I added an extra space for the null byte, it is mandatory if you want to handle name as a propper string. Also note that once the char array is given a size, it will not change, so when you store other strings in name keep that in mind.
The other problem is gets, you should never use it, it's a very dangerous function, it does not check the bounds of the destination buffer and therefore can easily cause a buffer overflow and that can cause all kinds of trouble. Recent compilers don't even support it anymore as it was deprecated and later removed from the C standard.
Even those which do still support it often issue warnings similar to:
warning: the `gets' function is dangerous and should not be used.
Here are two examples of the output of two modern compilers when you use it.
Summarizing and concluding, use fgets instead:
fgets(name, sizeof name, stdin);
When you use arrays in C you are using a fixed memory space. If I want to save "Hello World!" in memory, I have to reserve an array of length 13. In C it looks as:
char aString[13] = "Hello World!"
It may go as high as 20, but no lower than 13. Why? Strings have characters that we care and the last one is the null character (its value is 0). So, you need to reserve thirteen characters.
In your code you are reserving only 1 byte (1 character). At least, you have to reserve 15 bytes.
Try this code:
#include<stdio.h>
int main()
{
char name[15]="smti prajapati";
printf("Print the name througth the initilizing : ");
puts(name);
printf("Enter the name : ");
gets(name);
printf("Print the name througth the user : ");
puts(name);
return 0;
}
I compiled the code without problems. Also, you are able to not specify the length and It is going to work right. The best solution is dynamic memory. Avoid gets(). It has security issues. Instead, use fgets().
You have a number of misunderstandings. Let's look at them in order.
in the c language we know, the string is known as a null-terminated character** array
In C, a string is a null-terminated array of char. It is very common to refer to a string using a character pointer, char *. It may have been a typo when you said "character**", but type char ** is a pointer-to-pointer, which is something else.
when we declare char name[5]; it means the string store at least 4 characters value and null value.
Correct.
char name[1]="smti prajapati";
This is incorrect. Your compiler correctly warned you: warning: initializer-string for array of chars is too long
when we have entered a name that contains more than 5 characters it is accepted and prints all characters.
Right. Sometimes, when you break the rules, you get away with it.
In this case, the compiler does not throw the warning.
Right. C does not always detect or complain about buffer overflow. In general, it is your responsibility to make sure your arrays are allocated large enough for the strings you try to store in them.

Why does a certain part of the code output Segmentation Fault?

I'm making this console application where the user has to enter inputs. However, when the code gets to the part where the user inputs a file name which then gets added into a file path using strcat, it outputs Segmentation Fault..
Here is the full code:
int main(int argc, char *argv[])
{
char theFilePath[512];
char theIP[20];
char theFile[100];
char password[1];
char username[10];
printf("Username: ");
scanf("%s" , &username);
printf("Enter password: ");
scanf("%s", &password);
printf("Enter IP: ");
scanf("%d" , &theIP);
printf("Please specify the file: ");
scanf("%s" , &theFile);
strcat(theFilePath, "./passfiles/");
strcat(theFilePath, theFile);
strcat(theFilePath,".pf");
sprintf(theFilePath,"%s",theFilePath);
if (!(file_exist (theFilePath)))
{
printf("The file cannot be found in the path %s", theFilePath);
exit(EXIT_FAILURE);
} else
{
printf("The file exists!");
}
}
Any ideas why it does that?
Thanks in advance!
You have (at least) a couple of issues.
The first is the fact that you generally shouldn't be using an unbounded %s is scanf since it does not protect against buffer overflows (very similar to gets, which was deprecated in C99 and removed from C11).
This is doubly important when your buffers are pitifully small such as char password[1] which means, with the null terminator, all your passwords will have to be zero characters long. Now I'm no world-famous security researcher but I'm reasonably confident there's a security hole there in that scheme somewhere :-)
There are far safer options when needing user input, such as the function that can be found here, one that protects against buffer overflow and provides information on (and recovers from) the user trying to enter too much data.
The second is relying on uninitialised memory. The theFilePath variable is not initialised so may contain arbitrary data in it, yet your use of strcat expects it to contain a num-terminated string. That's a bad assumption to make and can be fixed by simply making the first strcat into a strcpy or, since it's always being set to the same initial value, doing that as part of the variable declaration itself:
char theFilePath[512] = "./passfiles/";
And, as an aside, assuming you're using a modern C compiler, you would be better declaring the variables at the point where you need them, rather than all at the top of the function, meaning this declaration should go where the current (errant) strcat currently is. Localising your declaration and use greatly aids readability.
You may also want to think about the usefulness of the statement:
sprintf(theFilePath,"%s",theFilePath);
Even if it works, it's effectively a no-op since all it does is copy some data to exactly the same place as it currently exists. In any case, it's not guaranteed to work since the standard quite clearly states in C11 7.21.6.6./2:
If copying takes place between objects that overlap, the behavior is undefined.
The character array
char theFilePath[512];
was not initialized by a string. So you may not use the standard C function strcat that concatenates strings. As result the program has undefined behavior.
You could initialize it for example either like
char theFilePath[512] = "";
or like
char theFilePath[512] = { 0 };
or like
char theFilePath[512];
theFilePath[0] = '\0';
Take into account that the scanf function is not safe. It is better to use function fgets.
Also you have to write
printf("Username: ");
scanf("%s" , username);
^^^^^^^
instead of
printf("Username: ");
scanf("%s" , &username);
^^^^^^^^^
Arrays are implicitly converted (with very rare exceptions) to pointers to their first elements in expressions.
While the above answers are all helpful and correct, I would like to offer a slightly different perspective.
scanf is safe if used safely. For example,
char username[10];
scanf("%10s" , username);
is safe. Unfortunately it's not possible to pass sizeof username to scanf.
For filenames, Posix defines PATH_MAX in limits.h as the maximum valid length of a filename. If your system doesn't supply that definition, er, I recommend switching to one that does. In a crunch, MAX_PATH is available on Windows.
I also suggest looking at the man page for getopt(3). While it's useful to learn how to use scanf, it's good practice to accept command-line options for user-provided information that is needed only at startup time.
Finally, see what you can do to crank up your warning level. My recent version of clang, for example, flags your incorrect use,
$ cc -std=c11 addr.c -o addr
addr.c:9:16: warning: format specifies type 'char *' but the argument
has type 'char (*)[10]' [-Wformat]
scanf("%s" , &username);
~~ ^~~~~~~~~
1 warning generated.
Such warnings provide feedback quicker even than questions on SO. ;-)

scanf() works despite 0-length buffer and compiler warning. What is going on?

My compiler (clang) shows this message:
11:17:warning: format specifies type 'char *' but the argument has
type 'char (*)[0]' [-Wformat]
scanf("%s", &name);
~~ ^~~~~
1 warning generated.
from the following code (greetings program):
/*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[0];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", &name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
What is actually going on, and how can I fix it?
In order to understand this, you have to understand what scanf is doing. scanf in this case is reading a string from stdin, and placing it into a buffer that you give it. It does not allocate that space for you, or detect overflow. You need to allocate sufficient space for your string. As it stands now, you are allocating zero space for your string, so everything is an overflow. This is a major bug.
Say instead of char[0], you did char[40], as another user suggests.What if the user of your program writes more than 40 characters? This results in undefined behavior. Essentially, it will write to memory you don't want it to write to. It might cause a segfault, it might result in crucial memory getting overwritten, or it might happen to work. This is a weakness of scanf. Look into fgets. You tell it the size of your buffer, and input will be truncated to fit.
Of course, that has nothing to do with your warning. You're getting a warning because referring to the name of an array is the same as referring to a pointer to its first element, i.e. name <==> &(name[0]). Taking a pointer to this is like taking a pointer to a pointer, i.e. &name <==> &&(name[0]). Since scanf is looking for an argument of type char*, and it's getting a pointer to that, the type checker complains.
Your code exhibits "undefined behavior." This means anything could happen. Anything.
You are passing a zero-length array to scanf(). Also, you are not passing the array length in the format string. This results in a buffer overflow vulnerability (always, in the case of a zero-length target array).
You need something like this:
char name[51];
scanf("%50s", name);
Note the %50s now specifies the size of the target array (less one, to leave room for the null terminator!), which avoids buffer overflow. You still need to check the return value of scanf(), and whether the input name is actually too long (you wouldn't want to truncate the user's input without telling them).
If you're on Linux, check out the tool called valgrind. It is a runtime memory error detector (among other things), and can sometimes catch errors like this for you (and much less obvious ones, which is the main point). It's indispensable for many C programmers.
Just change this:
scanf("%s", &name);
to:
scanf("%39s", name);
and this:
char name[0];
to:
char name[40];
Also to you have to end it with a '\0' with:
name[39] = '\0';
Depending on how robust you want this to be you will want to reconsider the approach. I guess the first thing is whether you understand the type you are using when declaring char name[ 0 ]. this is a 'zero-sized' array of byte-sized characters. This is a confusing thing and it wouldn't surprise me if its behaviour differs across compilers...
The actual warning being complained by the compiler is that the type doesn't match. If you take the address of the first character in the array you can get rid of that (i.e. use &( name[ 0 ] ) in the scanf call). The address of name is its location on the stack - it just so happens that the array implementation uses that same location to store the array data, and name is treated differently by the compiler when used on its own so that the address of an array is the same as the address of its first element...
Using char name[ 0 ] leaves you open to causing memory corruption because there is nowhere for the string to be read, and implementation details may just luck out and allow this to work. One simple way to fix this is to replace 0 with a meaningful number which you take to the maximum length of the input string. Say 32 so that you have char name[ 32 ] instead... however this doesn't handle the case of an even longer string.
Since we live in a world of lots of memory and large stacks you can probably do char name[ 4096 ] and use 4KB of memory for the buffer and that will be absolutely fine for real world usage.
Now... if you want to be a little anal and handle pathological cases, like a user leaning on some keys whilst asleep for hours before pressing enter and adding some enormous 8000 character long string there are a few ways to handle that too with 'dynamic memory allocation', but that might be a bit beyond the scope of this answer.
As an aside, from what I understand char foo[ 0 ] is intentionally valid - it may have originated as a hack and has a confusing type, but is not uncommonly relied on for an old trick to create variable sized structs as described in this page from the GCC online docs
char name[0]; ---> char name[100];
/* You need to allocate some memory to store the name */
2.scanf("%s", &name);----> scanf("%s", name);
/* scanf takes char* as an argument so you need to pass string name only. */
i don't think that scanf("%(length - 1)s", name); is needed.
Because %s is used to reads a string. This will stop on the first whitespace character reached, or at the specified field width (e.g. "%39s"), whichever comes first.
except these don't tend to be used as often. You, of course, may use them as often as you wish!
/
*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[100];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
Because the correct way is
scanf("%s", name);
/* ^ no ampersand
and what is
char name[0];
you should specify a non-zero length and use it for scanf length specifier
scanf("%(length - 1)s", name);
/* ^ sunstitite with the value */
there were several problems with the OPs posted code
the following fixes most of them
I includd comments to indicate where the problems are
int main ()
{
//char name[0]; // this did not allow any room for the name
char name[100] = {'\0'}; // declare a 100 byte buffer and init to all '\0'
printf("-------------------\n");
printf("Write your name:, max 99 char \n"); // 99 allows room for nul termination byte
printf("-------------------\n");
//scanf("%s", &name); // this has no limit on length of input string so can overrun buffer
if( 1 == scanf("%99s", name) ) // 1) always check returned value from I/O functions
// 2) no '&' before 'name' because
// arrays degrade to pointer to array when variable
// name is used
// 3) placed max size limit on format conversion string
// so input buffer 'name' cannot be overflowed
{ // then scanf failed
perror( "scanf failed for name" );
return(-1); // indicate error
}
// implied else, scanf successful
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
return(0); // indicate success
} // end function: main
You are reading a "string", thus the correct way is:
scanf("%s", name);
Why does the compiler complain? When you provide an argument in scanf, you provide the memory location of the variable. For example:
int x;
scanf("%d", &x);
&x is int *, i.e., a pointer to an integer, so x will get the correct value.
When you read a string, you're actually reading many char variables together. To store them, you need a char * array; well, name is char * on its own, so no need to write &name. The latter is char **, i.e., a 2-dimensional array of char.
By the way, you also need to allocate space for the characters to read. Thus, you have to write char name[20] (or any other number). You also need to provide a return 0; in your int main().

trouble printing after allocating memory

After using malloc, name gets printed but after allocating memory and typing in a string, puts doesn't print the string at all, neither does printf...why is this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *name;
int size;
printf("enter the size if name below\n");
scanf("%d", &size);
name =(char*) malloc(size * sizeof(char));//since my compiler returns pointr of type void, you have specify whether (int*) or (char*)
if (name== NULL)
printf("memory allocation failed,,,\n");
printf("%s\n",name);
printf("enter name below\n");
scanf("%s", name);
printf("name is\n%s", name);
name = (char*)realloc(name, 100*sizeof(char));
if (name == NULL)
printf("failed\n");
gets(name);
getchar();
puts(name);
free(name);
return 0;
}
First things first, malloc/realloc do not return void, they return void* which is perfectly capable of being implicitly cast to any other pointer type. It's a bad idea to do so explicitly in C since it can hide certain subtle errors.
In addition, sizeof(char) is always one, you do not need to multiply by it.
Thirdly, using gets is a very bad idea since there's no way to protect against buffer overflow. There are much better ways to do user input.
As to the specific problem, I suspect it's most likely still sitting around at the getchar. gets will get a line from the user (including the newline character) but, unless you enter another character (probably a full line if it's using line-based I/O), it will seem to hang. Check this by simply hitting ENTER again after you've entered the name.
Try either fgets() or scanf() at the place of gets().It will work
The program that you have posted causes undefined behavior. This is because of
printf("%s\n",name);
There is nothing in the variable name and you are trying to print the value in the allocated memory. First you need to assign some value to name before printing it.

Resources