-
char pointer error
Hi,
I'm pretty new to C programming, so bear with me if this has a simple answer.
I have an error that seems very strange to me. The following code when run produces an error and crashes.
Code:
#include <stdio.h>
#include <string.h>
int main ()
{
int i;
char *str;
gets(str);
return 0;
}
The strange thing is that if i get rid of the or if i put the after the there is no error. Also, the can be replaced by an analogous scanf function and the same error results. The same error also results when using a double, float, char etc... instead of an int.
However, when I declare str as for example, there is no error.
Any ideas?
Thanks for your help.
-
> The following code when run produces an error and crashes.
Consider yourself lucky then.
For some people, it runs perfectly (it's still wrong though), but because it "works", they think they're doing something right.
> char *str;
OK, this is a pointer - but where is it pointing?
You didn't say str = something; so it's just going to be some uninitialised (random) value. Basically, you're about to try and overwrite someone elses (or some non-existant) memory.
> gets(str);
oops, where did your input go?
Right over memory you didn't own.
Also, gets() is the world's most evil function - read this FAQ
http://faq.cprogramming.com/cgi-bin/...&id=1043284351
> The strange thing is that if i get rid of the ... or if i put the ... after the ... there is no error.
So you get a different random location go mess about with - still doesn't make it any more correct.
> can be replaced by an analogous scanf function and the same error results.
Writing to where uninitialised pointers point to is always bad, it doesn't matter which function you use to do it.
> However, when I declare str as char str[4]; for example, there is no error.
Well that sets aside 4 chars which you can modify.
But that still doesn't make it correct to use gets() (See the FAQ)
-
Ok so lemme see if I got this.
When I write the pointer named str simply contains whatever address happened to be lying around in that memory location where str was created. And therefore, when I try to gets() some characters starting at that address, it will be stored beginning at whatever that address in str happened to be (which might be an invalid location). Is this right so far?
Ok so, if instead I write
Code:
char *str = "abcdefg";
this doesn't seem to help. This is another thing i'm not really clear on. Does the string "abcdefg" just get stored in some random location, and then str points to that location?
If instead I write
Code:
char c;
char *str = &c;
then everything seems to work fine. However, I get the feeling that this is not good because if more than one character is stored starting at &c then it might start overwriting some other memory that it's not supposed to.
How, then, can I go about storing a string? Is the only way to create a sufficiently large char array?
Thanks for your help.
-
> Is this right so far?
Yes.
> Does the string "abcdefg" just get stored in some random location, and then str points to that location?
Not an entirely random location - the compiler creates some space, stores the string in that space, then points str to the start of that space.
printf( "%s\n", str );
prints the obvious thing.
> char *str = &c;
As you said, this is only good for storing one character, and trying to store more will overwrite something you shouldn't.
> How, then, can I go about storing a string?
Code:
char buff[BUFSIZ]; /* BUFSIZ is a constant in stdio.h */
fgets( buff, BUFSIZ, stdin );
> Is the only way to create a sufficiently large char array?
There is no standard "get a string of any length" call, but you can call fgets() in a loop to get a large amount of input over many calls. Combined with memory allocation you can then read as much input as you've got memory to store it.
-
Ok one last question. In the following
Code:
#include <stdio.h>
#include <string.h>
int main (void)
{
int i;
char *str = "xyzabc";
gets(str);
return 0;
}
I still get an error.
Now when the computer sets aside memory for the string "xyzabc", I assume it will only put it in valid memory, memory that isn't already used, and isn't invalid etc.. And str now points to the first location of the 'x'.
So why does this still produce an error after inputting to gets(), even when inputting a string shorter than the initialized one?
-
>>char *str = "xyzabc";
This is a pointer to a string literal; you're not allowed to write to string literals. If you want storage, use an array (str[SIZE]) or dynamic memory allocation (malloc()).
-
-
-
Ok, so the reason that last one didn't work is because I am not allowed to overwrite string literals stored in memory?
So statements like
Code:
char *str = "abc";
str = "qwerty";
str = "asdf";
are perfectly fine (because new memory locations for each string are created), whereas statements like
Code:
char *str = "abc";
fgets(str, 4, stdin);
are WRONG (because I am trying to overwrite a string literal) and should never be used?
Hopefully I've got this... Thanks for the help.