I have this recursive function which creates all possible strings from a dictionary and encrypt them so that they can be compared with some saved hashes.
Earlier, I had some predefined value for the max length of passwords but I tried to change it with argv[1].
But when I execute my program, I get a Segmentation Fault with not explanation.
By the way, all the includes are present as they should but I didn't put them in the post since it is somewhat bugged.
int recur(char * mot , char * tab,int l,int max_l)
{
// Because this was an exercice we had to do in class , i deleted this part
// so some of my classmates dont copy/paste my code
// if you are interested , contact me
int main(int argc, char *argv[])
{
char letters[36] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9'};
char s[10]="";
s[9]='\0';
int l=0;
int max_l;
sscanf (argv[1],"%d",&max_l);
printf("max_l : %i\n",max_l);
printf("Debut ! \n");
recur(s,letters,l,max_l);
}
Thanks for your time!
printf("Argv[1] : %s\n", max_l);
This is undefined behavior. You are giving wrong format specifier. That's why you get seg fault you are trying to print an int using %s format specifer. It looks for the \0 and then it doesn't. So it accesses some memory which it shouldn't resulting in UB. (And that resulted in segmentation error).
It should be
printf("Argv[1] : %d\n", max_l);
Also another major problem is not every control flow of this recursive function returns int. This is a pathway to bigger problem. In case the there is no return value when one is expected the behavior will be undefined.
Related
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;}
Here's more code I whipped up since i was having trouble with my major program that I now fixed.
I have a function which modifies a series of bytes. In this example, the function is supposed to fill up the first 9 bytes of the char array with the numbers 1 through 9 consecutively.
Two tests are run. The first one is calling the function where the parameter is (char*)&myvar. The second test only uses myvar as a parameter. I thought I always had to use an & in front of a char array pointer when I want the string returned in the parameter portion of the function.
Why does this program only work when I don't prepend (char*)& to my char array variable?
When I do apply it, I receive a segmentation fault.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int func(char* abc){
char *p=abc;
int n;
for (n=1;n<10;n++){
*p=(unsigned char)(n+48);p++;
}
return 0;
}
int main(){
char vars[1000]="234";
char *myvar=vars;
printf("Function test\n");
int result=func((char*)&myvar); //causes segfault
printf("Function result %s\n",myvar); //segfault here
printf("Function test again\n");
int result2=func(myvar); //works
printf("Function result %s\n",myvar);
printf("DONE\n");
return 0;
}
Why does this program only work when I don't prepend (char*)& to my char array variable?
Because doing that is completely wrong and not a thing that makes sense.
I thought I always had to use an & in front of a char array pointer when I want the string returned in the parameter portion of the function.
You don't. (Also, you do not have a "char array pointer", and "when I want the string returned in the parameter portion of the function" doesn't make sense.)
When you need to pass a char * to a function that takes a char *, you do not need to put any special prefix in front of the pointer. You just pass it directly, the way you did with
int result2=func(myvar);
You could also have passed in vars, due to the automatic conversion from an array to a pointer to its first element, just like you were able to do char *myvar=vars; without any special casting.
So I am new to the C language, I am attempting to write a program that outputs text in either upper or lower case, by inputting either -u or -l. The program compiles, however when I run it, it gives me a segmentation fault. Why?
#include <stdio.h>
#include <string.h>
int main(int argc, char*argv[]){
int i;
int j;
int k;
if(strcmp(argv[1],"-u")){
for(i=0;i<argc;i++){
printf("%s ",toupper(argv[i]));
}
}
else if(strcmp(argv[1],"-l")){
for(j=0;j<argc;j++){
printf("%s ",tolower(argv[j]));
}
}
else{
for(k=0;k<argc;k++){
printf("%s ",argv[k]);
}
}
}
toupper & tolower take an int representing a character and returning an int representing that character as upper or lower case (respectively).
You're doing 2 things wrong with that:
You're passing in the address of a char array (not a single character)
You're using the returned value (int) as if it was a char array (passing it as an input to printf with "%s")
So you're getting some garbage out of the function, and then sending printf into unmapped memory address -> that's your seg-fault.
To make life easy, also consider using the getopt command.
Here you will find an example: http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt
I'm working my way through a book on operating systems, and some of the book's sample code is giving me a runtime segmentation fault. I'm somewhat new to C from Java, and I'm hoping someone can point me in the right direction.
The little program here is supposed to generate a simple shell, read a command in and fork a process to execute it. The problem is in the book's code itself, at the "scanf" function call; when I input something at the "osh>" prompt, I get a segmentation fault.
Form what I know about C, I think memory might need to be allocated for the args array, but since it's an array declared directly in the main function, I think I might not need to. I figure that if I did, it would be in the book's code.
Anyway, here's the code that generates the fault:
char* args[MAX_LINE/2 + 1]; /* command line (of 80) has max of 40 arguments */
int should_run = 1;
int i, upper;
while (should_run){
printf("osh>");
fflush(stdout);
scanf("%s", args); /* THIS CAUSES SEGFAULT */
char* localArgs[3];
char* pch;
/* ... */
Thanks in advance for the help. Learning memory management in C is quite the journey.
You are passing an array of pointers to scanf(), it expects an array of char.
An example of how to use scanf() correctly to scan a text string would be
char string[100];
if (scanf("%99s", string) == 1)
{
printf("scanned string: %s\n", string);
}
else
{
printf("error: unexepected error in `scanf()'.\n);
}
Read the link throughly to understand why I wrote this code like I did, if you do you will start to understand how scanf() works, and when you do you will start writing more robust programs, and probably stop using scanf() too.
char* args[MAX_LINE/2 + 1];
This is creating an array of size (MAX_LINE/2+1) of char pointers. If you want to use one of these char pointers as string, you must allocate them:
args[which_arg] = malloc(arg_max_length*sizeof(char));
And to read a text into it:
scanf("%s", args[which_arg]);
int main(int argc, char *argv[]){
struct protoent *proto;
char **p_aliases;
if(argv[1]==NULL){
char name[25];
printf(" give a valide protocol name\n");
scanf("%s",name);
proto = getprotobyname(name);
}
else{
proto = getprotobyname(argv[1]);
}
if(argv[1]==NULL){
printf("%s the protocol name is :\n",proto->p_name);
printf("%s the protocol alias is\n",proto->p_aliases);
printf("%d the protocol number is \n",proto->p_proto);
return 0;
}
}
// i'm not getting the proper output, just a fragmentation fault
Problems with this code:
argvc < 2 would be more robust than argv[1] == NULL, though that's probably not the issue here.
There's nothing to prevent scanf reading more than the 25 characters you've allocated.
The second if will mean there is no output at all if argv[1] is non-null.
getprotobyname returns a null-pointer when the name is not recognised, but you don't check.
You try to print proto->p_aliases, but that has type char **, so you probably need to print proto->p_aliases[0] (and should probably check that is non-null).
Anyway, besides all that, when you get a seg fault it's better to run the code under an debugger before you go ask other people to do your work for you. The debugger will probably tell you exactly where the problem is, and if it doesn't you can step through the code and narrow it down very easily.