0

Possible Duplicate:
why does c allow initialization of string without declaration?

I am trying this rather simple code:

#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);

printf("%s",name);
}    

But for some reason, after I enter a name and press Enter, the program hangs and gives a message like Program has stopped working. However when I remove the 2nd character pointer declaration, that is the char *surname;, it works just as expected. What is the problem here?

Community
  • 1
  • 1
SexyBeast
  • 7,913
  • 28
  • 108
  • 196

4 Answers4

3

You have not allocated memory for the pointers, so the scanf accesses arbitrary unspecified memory, which is undefined behaviour.

You need to pass pointers to sufficiently large memory blocks to scanf, either declare

char s1[100], s2[100];

(if 100 is large enough), or malloc memory

char *s1 = malloc(100);
char *s2 = malloc(100);
if (!s1 || !s2) {
    // malloc failure
    exit(EXIT_FAILURE);
}
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
2

You are writting into unallocated memory. That is undefined behavior,

You can do 2 things here:

  1. declare your arrays of chars as having a fixed size at compile-time like this: char name[100]; (which means you can't change their size at runtime)
  2. allocate room for char *name using malloc() or calloc() functions in stdlib.h

In any case you absolutely have to make sure you only allow the user to input the amount of bytes you allocated, otherwise bad things can and will happen!

A small study on what an evil person can (and will ;) do if you fail to define said boundaries can be found here: http://www.cultdeadcow.com/cDc_files/cDc-351/

Gung Foo
  • 13,392
  • 5
  • 31
  • 39
  • I don't understand. Why then, it works if the second declaration is removed? – SexyBeast Oct 27 '12 at 12:36
  • 1
    as i said.. "unedfined behavior" you are writing "somewhere" into unstructurd memory.. anything can happen and what will happen depends on the compiler and/or platform. most likely the kernel realizes that you are illegaly overwriting a pointer you declared right after the first one (which makes it likely that you write into it right at the 2nd character) and prevents you from doing that. – Gung Foo Oct 27 '12 at 12:37
  • @Cupidvogel UB doesn't mean the program **will** crash, it means the program **can** crash. –  Oct 27 '12 at 12:42
  • @GungFoo Also, please add the stack-based (automatic) array option to your answer. –  Oct 27 '12 at 12:43
  • 1
    @H2CO3 i made your requested edits + added some fun stuff :) – Gung Foo Oct 27 '12 at 15:32
1

Because you didn't allocate memory for it, and the string you put in it screws the code of the program. Try to use sscanf and getline:

#include <stdio.h>

int main()
{
  int nbytes = 100;
  char *my_string;
  int int1, int2, int3;
  int args_assigned;

  args_assigned = 0;

  while (args_assigned != 3)
    {
      puts ("Please enter three integers separated by whitespace.");
      my_string = (char *) malloc (nbytes + 1);
      getline (&my_string, &nbytes, stdin);
      args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
      if (args_assigned != 3)
    puts ("\nInput invalid!");
    }

  printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);

  return 0;
}

check out this:

Reading in a variable length string user input in C

and this :

http://en.wikipedia.org/wiki/Buffer_overflow

Community
  • 1
  • 1
0x90
  • 39,472
  • 36
  • 165
  • 245
1

You declare a pointer and do not give it a valid memory address, it points to a random addrss. You cannot read or write with this pointer. Pointers should be used like this:

char s1[100],s2[100];
char * name=s1;
char * surname=s2;
Jerry
  • 435
  • 4
  • 12
  • 1
    Why those extraneous pointers? Just pass `s1` and `s2` to `scanf()`. –  Oct 27 '12 at 12:41
  • Thanks. Another question, pointers, whatever they point to, are themselves actually integers storing addresses, right? So `*p = "foo"` will place some integer value into `p`, which will be the address where the program has stored **foo**, right? How come then we can assign strings to `p`, like `p = "barbar"`? – SexyBeast Oct 27 '12 at 12:42
  • char *p; *p ="foo" is wrong. p="foo" is right. because in C, strings are char pointers. – Jerry Oct 27 '12 at 22:56
  • (1)Yes, pointers are actually integers, more accurately, special integers which value is memory address. In some IDE, you can assign a integer to a pointer `char * p =10;` And we can add some value to a pointer: `p+=20;` Of course, when you add an number N to a pointer, the value of the pointer will increase not N but N*sizeof ( element ). (2)Your code: `char *p; *p ="foo";` is wrong. `p="foo"` is right. because in C, strings are char pointers. Pointers should be assigned to pointers. – Jerry Oct 27 '12 at 23:02
  • @H2CO3: Just use `s1` and `s2` is OK. But the author of the question want to know how to use pointer. So I must use pointer as a demo. – Jerry Oct 27 '12 at 23:08