Hi there,

This is my first time working with an unsafe language, so naturally my first code would be full of memory-related bugs. I still have no idea how I ought to approach some of the problems I've been getting, and I've been resisting asking for help as much as I could.

The assignment I've been given is a buttload of work, so I'd rather not bog anyone down with too much of it. At the moment, I'm trying to work out how to design a menu() function that gives main() both the function choice the user wants and the arguments for that function. Here's what I've got so far:

struct REPLY {
	char use[256];
	char pass[256];
	char type[64];
	char nuse[256];
	char npass[256];
	char ntype[64];
	int option;
};

struct REPLY *reply;

int menu (void)
{
	int o;
	printf("Please type a number corresponding to the following options:\n");
	printf("1. Add\n");
	printf("2. Delete\n");
	printf("3. Edit\n");
	printf("4. Purge\n");
	printf("5. Quit\n");
	scanf("Selection: %i\n", o);
	reply->option=o;
	printf("\n\n%i\n\n\n", reply->option);
	switch(reply->option){
		case '1':
		{
			printf("Please provide the username.\n");
			scanf("%s\n", &reply->use);
			printf("Please provide the password.\n");
			scanf("%s\n", &reply->pass);
			printf("Please provide the user type.\n");
			scanf("%s\n", &reply->type);
			break;
		}
		case '2':
		{
			printf("Please provide the username.\n");
			scanf("%s\n",&reply->use);
			break;
		}
		case '3':
		{
			printf("Please provide the username.\n");
			scanf("%s\n",&reply->use);
			printf("Please provide the password.\n");
			scanf("%s\n",&reply->use);
			printf("Please provide the new username.\n");
			scanf("%s\n",&reply->nuse);
			printf("Please provide the new password.\n");
			scanf("%s\n",&reply->npass);
			printf("Please provide the new user type.\n");
			scanf("%s\n",&reply->ntype);
			break;
		}
		case '4':
		{
			break;
		}
		case '5':
		{
			break;
		}
	}
	
	return 0;
}

This code is saved as menu.c, which is included in the inclusion statements of the main function. I'm getting a segmentation fault at

reply->option=o;

and I haven't been able to find out why. I also get the sense main won't be able to access reply for some reason.

I just need a push, and it's probably so simple it went over my head, but can someone help me out?

line 22: >> scanf("Selection: %i\n", o);

You can't combine scanf() and printf() like that, and the parameter must be a pointer to an integer

printf("Selction: ");
scanf("%i", &o);

That dismissed one of the warnings, but I still get a segmentation fault at

reply->option=o;

Why is that even a problem?

All of the other warnings look like this:

menu.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[256]’

That dismissed one of the warnings, but I still get a segmentation fault at

reply->option=o;

Why is that even a problem?

struct REPLY *reply; is a pointer, anything you try to write to it it will produce a segmentation fault, since there's no memory allocated for it.

I'm never sure when to use malloc and when C allocates the memory for me. Thank you, I'll try that.

I'm never sure when to use malloc and when C allocates the memory for me.

For some, memory management in C, is a curse, nevertheless it is one of the strength of the language.

All of the other warnings look like this:

menu.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[256]’

After allocating memory for it, remove any & in front of those pointers to string like

scanf("%s\n", &reply->pass);

and the '\n' is not going to give you the intended result, neither.

Comments
This was extremely helpful! Thanks.

Success! This was the sort of push I needed. I'm not getting any warnings, and as far as I can tell the menu is working properly.

I might have questions later about how to get menu()'s reply back to main() since C's scoping is so complex. This is what I've done:

...

struct REPL *reply;

int menu (void)
{
	reply=(struct REPL*)malloc(sizeof(struct REPL));

...

Since reply is declared globally, will main() be able to see and use it after menu is finished?

@Aia, thanks for your help - I really appreciate it.

Alright, more segmentation faults...

This time I'm trying to parse a file into a linked list. The intent is to decrypt and read the file line-by-line, separating a line into parts and storing those parts into a struct.

I'm only getting the segmentation fault when the file, password.csv, already exists, for some reason. If it's starting anew the program behaves normally.

GDB says the problem is in this line. The whole function is pasted below.

while(fgets(c, 600, fin)!=NULL)

It happens in this function:

int parse (void){
	cipher(0);
	FILE *fin=fopen("password.csv", "rt");
	//processing
	char *c;
	while(fgets(c, 600, fin)!=NULL){
		char use[256];
		char pass[256];
		char type[64];
		strcpy(use, strtok(c,", "));
		strcpy(pass, strtok(NULL,", "));
		strcpy(type, strtok(NULL,", "));
		push(use, pass, type);
	}
	fclose(fin);
	return 1;
}

I'd really appreciate your thoughts.

char *c; is a pointer, again, it doesn't point to any proper memory allocated to it. while(fgets(c, 600, fin)!=NULL) Guess what you are trying to do there? Yeap! Trying to write to poor char *c that it doesn't have any proper memory available for it.

Aw man, I thought C handled chars! It's just one byte! Okay, thanks again for your help.

As a general rule, do segmentation faults happen because memory isn't allocated? I'd guess with beginner C it wouldn't be anything fancier.

Aw man, I thought C handled chars! It's just one byte! Okay, thanks again for your help.

As a general rule, do segmentation faults happen because memory isn't allocated? I'd guess with beginner C it wouldn't be anything fancier.

:) segmentation faults occur when you are trying to access memory that you are not suppose to. e.g.

int *x; /* declares a pointer to int, the variable x is holding a random value which will be used to represent an address */

If you don't make that x to point to something meaningful, who knows what that random value is going to try to represent, and access as an address. Accessing that random address to write into, can create a segmentation fault.

This article has been dead for over six months. Start a new discussion instead.