PDA

View Full Version : Can somebody explain me a mistake in a string?


pandol
12-01-2007, 10:14 AM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
struct tel
{
char name[20];
int telno;
char *address;
};

struct tel *entry;

entry = (struct tel *) malloc (sizeof (struct tel));

scanf("%s\n", (*entry).name);

scanf("%d\n", &(*entry).telno);

scanf("%s\n", (*entry).address);

printf("%s\n", (*entry).name);
printf("%d\n", (*entry).telno);
printf("%s\n", (*entry).address);


return 0;
}

The program compiles but is does not run as it should!!
I think the mistake lays in the following line: char *address;
But I do not understand why?

shyam
12-01-2007, 10:37 AM
since address is only a pointer to character and therefore can only assign it values of strings that are already allocated or allocate before assignment

ghell
12-01-2007, 04:54 PM
There are quite a few mistakes there. I think you are trying to make it more complicated than it needs to be. Try something like this:#include <stdio.h>
#include <malloc.h>

struct tel
{
char name[20]; /* Remember that this includes a 0 (nul) on the end so max length here is 19 */
int telno;
char* address;
};

int main(void)
{
/* Shows allocation of struct on the stack */
struct tel entry;
/* Shows allocation of address data on the heap. */
entry.address = (char*)malloc(40);

gets(entry.name);
scanf("%d\n", &entry.telno);
gets(entry.address);

printf("%s\n", entry.name);
printf("%d\n", entry.telno);
printf("%s\n", entry.address);

/* VERY important line if you use malloc */
free(entry.address);

return 0;
}
Note that "address" does not have to be on the heap, it could be on the stack (char address[40]) and the stack should be used wherever possible as it is faster and cannot leak. I just put it on the heap here to demonstrate the heap's usage. The heap should be used when storing large amounts of data like images among other uses but if you can use the stack, do. When you use the heap you MUST call free() on any data, as shown in the example. Not doing this causes memory leak.

This code also uses gets(char*) which gets a line from standard input. Scanf breaks at whitespace so "Foo Bar" with scanf would show just "Foo" and then the next call would show "Bar".

Also note that scanf needs to be given a pointer. char* and char[] are already pointers but if you have something like an int, you need to get a pointer to it with &myint.

Anyway, your problem is that you need to have allocated memory to put the string in. When you use malloc you get a pointer to some allocated heap space. When you use char[] you get an array (this is actually a pointer too but ignore that for now) of allocated memory on the stack. If you use char* foo = "bar"; you will also get space allocated on the stack (4 bytes in this case, for 'b, 'a', 'r' and 0 (nul) to terminate the string)

If you just use
char* foo;
scanf("%s\n" foo);
then the char pointer points to whatever address was at its memory location before it was created so when you try to write to it, it is probably writing to memory that isn't even part of your program (and hence crashes) and certainly isn't safe (even if it is pointing to memory within your program).