0

When I run this program, it allows me to enter the first name, then it gives me a segmentation fault.

I dont know why this happens or how to get rid of it.

#include <stdio.h>

int main (void)
{
        FILE *fp;

        fp = fopen("list.txt","a+");
        if (fp == NULL){
                 printf("File list.txt could not be opened.");
        }

        for(int i=0;i<3;i++){
                char *name;
                char *str;
                char *sta;
                printf("Please enter your name: ");
                scanf("%s",name);
                printf("Please enter your street: ");
                scanf("%s",str);
                printf("Please enter your state: ");
                scanf("%s",sta);
                fprintf(fp,"%s,%s,%s\n",name,str,sta);
        }
        fclose(fp);
}
Davis Herring
  • 36,443
  • 4
  • 48
  • 76
Dr.B
  • 1
  • 2
  • 1
    First question: What does your debugger say? – tadman Oct 22 '17 at 22:59
  • 2
    Hint: `char* name` is not a character buffer you can immediately use with `scanf`. It's not initialized. It's not allocated any space. It's going to explode. – tadman Oct 22 '17 at 23:00
  • [The documentation](http://www.cplusplus.com/reference/cstdio/scanf/) for scanf says: `... (additional arguments) Depending on the format string, the function may expect a sequence of additional arguments,` **each containing a pointer to allocated storage** `where the interpretation of the extracted characters is stored with the appropriate type.` (emphasis mine) – Les Oct 22 '17 at 23:13
  • Sorry for another dumb question, but is char name[10] the same as char *name = malloc(10) ? What subject should I search for to watch a youtube video to learn more? Dynamic memory allocation? – Dr.B Oct 22 '17 at 23:51

1 Answers1

0

what exactly does the compiler say when you try compiling this? Your problem seems most likely from the way you're using scanf. Yes, scanf takes addresses/pointers to variables but at this point the char * variables you have are not initialized and could most likely contain garbage in them. Use a char array (char [ ]) variable instead. Or alternatively, use some alternative method of Initializing your char pointers (char *) either by calling a dynamic memory allocator like malloc, or storing the address of some other preexisting array of characters.

And bonus: yes, char name[10] is the same as char *p= malloc(10). Char name[10] is an array of 10 characters each of which is a byte in size and the char "name" variable is implicitly a pointer to the first element of said 10 characters, and malloc(10) returns a pointer to 10 bytes in memory. Both generate pointers to 10 bytes.

redBhutan
  • 1
  • 2
  • Yes, I got it to work with char name[10] and char *name=malloc(10). I was wondering. Are these the same thing? Or is there a subtle underlying difference – Dr.B Oct 22 '17 at 23:58
  • I edited my answer to answer your comment. :) – redBhutan Oct 23 '17 at 00:03
  • Thanks for your help! – Dr.B Oct 23 '17 at 03:09
  • I would _not_ call `char a[10];` and `char *b=malloc(10);` the _same_; they both arrange to have 10 bytes available, but a pointer is not an array (for instance, `b` could be made to point elsewhere), and the heap is not the stack. – Davis Herring Oct 23 '17 at 03:17
  • @Davis has a good point. So yes, there are subtle differences and they do matter. – redBhutan Oct 23 '17 at 10:02
  • Thank you! So are there situations when I would want to use one or the other? – Dr.B Oct 23 '17 at 22:13
  • Also, it seems wasteful to allocate a certain amount of memory if the "name" that i record is much smaller than say 10 bytes in this case. Is there a way to allocate just enough memory to be more efficient? – Dr.B Oct 23 '17 at 22:14
  • I believe that's where dynamic memory allocation comes in. Look more into the standard library functions malloc, calloc, and realloc, and how to use them for allocating memory dynamically on the heap. Can't explain all that since this isn't a discussion forum. – redBhutan Oct 24 '17 at 09:00