tags:

views:

228

answers:

6

consider the code

#include<stdio.h>
int main(void)
{
   char* a;
   scanf("%s",a);//&a and &a[0] give same results-crashes 
   printf("%s",a);
   return 0;
}

why does this code results in crashing?whereas this code using character array works fine?

#include<stdio.h>
int main(void)
{
   char a[100];
   scanf("%s",&a[0]);//works fine
   printf("%s",a);
   return 0;
}

the difference being character array and pointer?but i knew that pointer just points to the first element that is &a[0] should work fine but upper code crashes for all three that is a,&a and &a[0]? the main thing i would to gather is how can i take input of a character pointer if i insist on using scanf only? i apologize if i am not clear. thanks in advance:)

+3  A: 

You have to allocate memory for a with malloc() before using it .

qrdl
@qrdl i would like to know the reason for crashing with reference to memory
CadetNumber1
Without allocating memory your `a` points to some random place in memory, which very likely doesn't belong to your process, thus attempt to access this memory results in segmentation fault.
qrdl
`int *a;` Just declares a pointer. It doesn't actually give it any memory to point to. `scanf` assumes the pointer you give it points to a memory space large enough for its needs. Since you never pointed `a` anywhere, the program crashes.
T.E.D.
+2  A: 

scanf needs a place where to put the characters it reads. You can pass it a pointer to a character array (what you do in your second example), or a pointer to some memory obtained in another way (say malloc()). In your first example, you pass it an uninitialized pointer, thus the problems you are observing.

AProgrammer
@aprogrammer you mean to say i need to initialize the pointer likechar* a=""
CadetNumber1
You need to initialize the pointer variable with a pointer value pointing to memory you can write to. What you propose here is to initialize it -- which is better than what you did -- but you can not write to that memory (and it is probably too small even if you could write there).
AProgrammer
+1  A: 

In the first example a is a "dangling pointer" - it's a pointer that contains the address of a somewhat random memory location. In most cases accessing this address will result in a crash. Bottom line: you need to allocate memory for a.

Paul R
+6  A: 

Because char* a; allocates space on the stack for a character pointer whilst char a[100]; allocates space for 100 characters.

In the former case, you need to allocate some actual memory for the pointer to point to. What's happening to cause your crash is that a is being set to some arbitrary value (you don't initialise it) and, when you scanf, that's where the data is being written. That's if you just use a, let's call that crash type number one.

If you use &a, it will write your input over the pointer itself which will leave you with a pointer that points who-knows-where, leading to crash type number two. That's assuming you haven't entered more characters than will overflow the pointer - that would corrupt the call stack leading to yet another crash situation (type three).

And as a word of advice, please don't use input functions that don't have bounds checking unless you're absolutely in control as to what data is presented to them. Even with a char[100], someone could cause a stack overflow in your code by entering more characters than will fit in your buffer.

I find the best thing to do is to use fgets (which can limit the characters read) in conjunction with sscanf (although if all you're getting is a string, sscanf is not really needed).

paxdiablo
+1  A: 

In you first code, a is an uninitialized pointer to char. You are trying to write to non-allocated memory or reserved memory.

You need to allocate memory for the input string with malloc().


int main(void) {
  char* s;
  /* ... */
  s = malloc(100 * sizeof(*s));
  if (s == NULL) {
    return 1;
  /* ... */
}
Bertrand Marron
+2  A: 

a doesn't point to anything. Or actually, it's uninitialized so it points somewhere, just not somewhere valid.

You could provide storage on the stack like you've already tried:

#include <stdio.h>
int main()
{
  char x[100];
  char *a = x; // a points to the storage provided by x on the stack
  scanf("%s",a); // should work fine
  printf("%s",a);
  return 0;
}

Note that printf("%s",x); yields exactly the same result, a is pointing to x, so that's where your string will 'live'.

Or you could have the memory management handle it by using malloc

#include <stdio.h>
#include <stdlib.h>
int main()
{
  char *a = malloc (100*sizeof(char)) // a points to the storage provided by malloc
  if (a != null)
    {
      perror ("malloc"); // unable to allocate memory.
      return 1;
    }
  scanf("%s",a); // should work fine
  printf("%s",a);
  free (a); // just remember to free the memory when you're done with it.
  return 0;
}

HTH.

EDIT
Also, before the comments start... This is very unsafe code, but I guess you're just trying to wrap your head around pointers, so I just tried to give you a nudge in the right direction. (If not you need to look into reading limited amount of data, make sure it fits in your buffers, if it's from some other source than a file, you need to make sure you got all of it, and so on, and so on).

roe