Segmentation fault with scanf and strings in C - c

I am a beginner with c, and I am having a problem with scanf and strings.
here is an example I wrote of my problem.
#include <stdio.h>
#include <string.h>
int main(void)
{
char* string;
scanf("%s", &string);
if (strcmp(string, "Foo") == 0) //segmentation fault here
printf("Bar");
}
basically, this code compiles, but when I run it I get a segmentation fault in strcmp()
if I replace the "string" in that line with "&string" it works, but I get this error from the compiler
/usr/include/stdio.h:362:12: note: expected 'const char * __restrict__' but argument is of type 'char **'
which makes me think that this solution is not really ideal.
also If I declare string like this:
char string[100];
that works without any warnings, but that is also not ideal because I am not sure how large the string is going to be.
Is there a better solution I'm missing here, or are these my only options?
thank you.

char* string;
scanf("%s", &string);
string is not pointing to any valid memory location. Allocate memory using malloc to an array of characters and copy input to it. Make sure allocated memory has space for null termination character. Remember to free the memory to avoid leaks.

Just try that code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char* string;
string=(char *)malloc(3); /*allocate the memory to string cahr pointer(default pointer point to single byte and if you print pointer variable don't used & character)*/
scanf("%s", string);
if (strcmp(string, "Foo") == 0)
printf("Bar\n");
}

While declaring a char *. it will not having any memory location. so you have to allocate a
memory location before you use that variable.
char *p;
p=malloc(sieof(char) * size of string);
then you use scanf() function. it will work properly.
when we are accessing a unknown memory(ie unallocated memory). then it will through the segmentation fault

Related

What is causing the program to crash in the code snippet below?

I'm trying to write a piece of code in C which takes an input(as string) from the file and adds it at the end of another string and prints it.
The program compiles perfectly in Visual Studio 2013 but crashes during run.
Can anyone please help me identify the problem with the code.
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
char input[255];
char str1 = "caingb";
char str2 = " ";
FILE *f;
f = fopen("rockyou.txt", "rt");
while (fgets(input, sizeof(input), f))
{
str2 = str1 + input;
printf("%s", str2);
}
fclose(f);
return(0);
}
These are the three warning messages I'm getting:
Line 8: warning C4047: 'initializing' : 'char' differs in levels of indirection from 'char [7]
Line 9: warning C4047: 'initializing' : 'char' differs in levels of indirection from 'char [2]
Line 14: warning C4047: '=' : 'char' differs in levels of indirection from 'char *
The easiest way to concatenate strings is with asprintf (for allocating sprintf, if you have it):
char *result;
char *a = "foo";
char *b = "barco";
asprintf(&result, "%s%s", a, b);
Note how easily this can deal with three or more strings, or interspersing stuff like in
asprintf(&result, "C:/%s/%s.exe", a, b);
Yours crashes because of the misdeclarations of str1 and str2 as char instead of pointers to char (that's what the warning messages tell you in some hard to understand way). Furthermore, C is not Java, and string concatenation is not done with +.
A good programmer would test result being non-NULL and probably free(result) once no longer needed.
If you like to concatenate strings in C you have to use strcat .
If you like to copy one string to another you have to use strcpy ...
In a few words for string assignments in C you have to use a built in function (strcpy, strcat, memcpy, snprintf etc). You can't just simply use the = operator as you do!
So your code would be something like this:
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
char input[255];
char *str1 = (char*)malloc(sizeof(char)*10);
strcpy(str1,"caingb");
char *str2=(char)0; //point to null..for initilization!
FILE *f;
f = fopen("rockyou.txt", "rt");
while (fgets(input, sizeof(input), f))
{
str2=(char*)malloc(sizeof(char)*(strlen(str1)+strlen(input))+1);
strcpy(str2,str1);
strcat(str2,input);
printf("%s", str2);
free(str2);
}
fclose(f);
free(str1);
return(0);
}
At the 2 lines of the code above that malloc function appears, you are basically allocating space on the memory, to store the variables that malloc gets called from. In your for the second malloc you need the size of each character (sizeof(char)) multiplied times the amount of the length of string 1 (strlen(str1)) plus the length of string 2 ('strlen(input)). That will give you the required memory in HEAP of your program to storestr2. For the first malloc i am just multiplying it by 10, since"caingb"` i 6 chars (so i am reserving a few more bytes...not a good strategy if you want to be a good coder ;-) ). Later by calling free you are de-allocating the space you reserved with malloc, because if you don't it will stick like that into memory even after program is done executing!
A more abstract idea of malloc (for example purposes) would be
char* string=malloc(15);
...and like that you allocated 15 bytes of memory for the pointer char *string. So in whatever this pointer points to, must not exceeds 15 bytes, or you will have memory leaks (aka segmantation faults in C).
For further reading, search yourself about stack and heap of a program in C.
Also always try out the man pages through the terminal of yours ( in Linux) . An example of this would be:
man malloc
..and voilla you will get a manual page for what malloc does. It might seems a little bit harsh to read those man pages at first, but give time to yourself! There is also an online version of them at http://man.he.net/
P.S. I haven't run the above code, but thats the general idea.

Char arrays and scanf function in C

I expected to get errors in following code, but I did not. I did not use & sign. Also I am editing array of chars.
#include <stdio.h>
int main()
{
char name[10] ="yasser";
printf("%s\n",name);
// there is no error ,
// trying to edit array of chars,
// also did not use & sign.
scanf("%s",name);
// did not use strcpy function also.
printf("%s\n",name);
return 0;
}
I expected to get errors in following code, but I did not.I did not use & sign.
scanf("%s",name);
That's totally ok as name is already the address of the character array.
It sounds like you have several questions:
calling scanf("%s", name) should have given an error, since %s expects a pointer and name is an array? But as others have explained, when you use an array in an expression like this, what you always get (automatically) is a pointer to the array's first element, just as if you had written scanf("%s", &name[0]).
Having scanf write into name should have given an error, since name was initialized with a string constant? Well, that's how it was initialized, but name really is an array, so you're free to write to it (as long as you don't write more than 10 characters into it, of course). See more on this below.
Characters got copied around, even though you didn't call strcpy? No real surprise, there. Again, scanf just wrote into your array.
Let's take a slightly closer look at what you did write, and what you didn't write.
When you declare and initialize an array of char, it's completely different than when you declare and initialize a pointer to char. When you wrote
char name[10] = "yasser";
what the compiler did for you was sort of as if you had written
char name[10];
strcpy(name, "yasser");
That is, the compiler arranges to initialize the contents of the array with the characters from the string constant, but what you get is an ordinary, writable array (not an unwritable, constant string constant).
If, on the other hand, you had written
char *namep = "yasser";
scanf("%s", namep);
you would have gotten the problems you expected. In this case, namep is a pointer, not an array. It's initialized to point to the string constant "yasser", which is not writable. When scanf tried to write to this memory, you probably would have gotten an error.
When you pass arrays to functions in C, they decay to pointers to the first item.
Therefore for:
char name[] ="yasser";
scanf("%s", name) is the same as scanf("%s", &name[0]) and either of those invocations should send shivers down your spine, because unless you control what's on your stdin (which you usually don't), you're reading a potentially very long string into a limited buffer, which is a segmentation fault waiting to happen (or worse, undefined behavior).
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
char *myName = (char *) calloc(10, sizeof(char));
*(myName)='K'; *(myName+1)='h'; *(myName+2)='a'; *(myName+3)='l'; *(myName+4)='i'; *(myName+5)='d';
printf("%s\n",myName);
scanf("%s",myName);
printf("%s\n",myName);
return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <string.h>
int main()//fonction principale
{
char name[10] ="yasser";
int longeur=0;
printf("%s\n",name);
scanf("%s",name);
longeur = strlen(name);
for (int i=0;i<longeur;i++) {
printf("%c",*(name+i));
}
return 0;}

*char into main and *char into a struct

The two following codes are similar but the first has a structure, the second not.
Why this code works (with no warnings)?
#include <stdio.h>
#include <string.h>
struct prova
{
char *stringa;
};
int main()
{
struct prova p;
strcpy (p.stringa, "example\0");
printf("%s\n", p.stringa);
return 0;
}
But the following code doesn't work?
Segmentation fault (core dumped)
With this warning:
code.c: In function ‘main’:
code.c:8:9: warning: ‘stringa’ is used uninitialized in this function [-Wuninitialized]
strcpy (stringa, "example\0");
#include <stdio.h>
#include <string.h>
int main()
{
char *stringa;
strcpy (stringa, "example\0");
printf("%s\n", stringa);
return 0;
}
Thank you!
Neither is correct because you copy to an address specified by an uninitialized variable. Therefore both programs invoke undefined behaviour.
The fact that one of the programs works is down to pure chance. One possible form of undefined behaviour is that your program runs correctly.
You need to initialize the pointer to refer to a sufficiently sized block of memory. For instance:
char *stringa = malloc(8);
Note that you do not need to add a null terminator to a string literal. That is implicit. So, given this memory allocation you can then write:
strcpy(stringa, "example");
You need to give the string some memory for it copy the characters to.
Use malloc
besides the first example does not compile.
When you write
struct prova
{
char *stringa;
};
int main()
{
struct prova p;
strcpy (p.stringa, "example\0");
notice that p.stringa points to nowhere in particular but you copy to it.

Segmentation fault (core dumped) using char*

i am new to c programming. i am getting Segmentation fault (core dumped) when i am
trying to print the string. please help.
#include <stdio.h>
#include <string.h>
int main()
{
char *ptr;
strcpy(ptr, "mystring");
printf( "%s\n", ptr);
return 0;
}
You haven't allocated any memory for your pointer to point at.
char array[MAX_LEN + 1];
char *ptr = array;
strncpy(ptr, "Cadence", MAX_LEN);
ptr[MAX_LEN] = '\0';
printf( "%s\n", ptr);
Please note that strncpy() can be a safer way to copy strings, since we specify the maximum number of characters to copy, which makes it harder to overrun the string and 'scribble' memory.
Update in response to comments: I've altered the above code to use a slightly safer pattern. You might also want to investigate strlcpy() (non-standard library).
When you declare char *ptr;, you allocate memory for a pointer to a char. But if you want to put a string inside the char, it will make an overflow.
Therefore, you have to allocate memory for your string :
char str[1024]; // which is the maximum string lenth that you will be able to put in str.
Furthemore, don't forget the null terminator (\0) that terminate every string and has the size of one char

Segmentation fault sprintf [c]

I need to pass two args to a shell script, here is the code:
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *script;
int lines = 1;
sprintf(script, "/...path.../line.sh %d %d", lines, lines);
system(script);
}
The script works well, ive tried. But I always get Segmentation fault. The question is: why?
Thanks
You are writing to the memory location pointed to by script which hasn't been allocated any memory.
Try something like:
#include <stdio.h>
#include <stdlib.h>
void main()
{
char script[100]; // Allocate as much as you need here for your string, not
int lines = 1; // necessarily 100
sprintf(script, "/...path.../line.sh %d %d", lines, lines);
system(script);
}
You need to allocate space for script
char *script = malloc(/* string size */);
To be able to use it.
You didn't allocate any memory for script.
char *script; creates a pointer, but it has to point to something you've allocated, in your case its value is undefined. Use malloc to allocate the memory, and free when you're done.
change this line:
char *script;
to this:
char script[255];
The sprintf tries to write the result string to script, which you haven't initialised.
You're not allocating any memory for the variable script. The sprintf function expects that its first param is a pointer to already-allocated memory, but your script is never initialized, which means that it's null or garbage.
You are formatting into "script" without allocating any memory to receive the formatted string.
Instead, allocate:
char script[1024];

Resources