|
|
Total Newbie using C
|
|
|
|
Senior User
Join Date: Sep 2000
Location: UK
Status:
Offline
|
|
Hi,
I'm trying to lean C with Xcode, and am trying to do a very simple thing : change the contents of a char array.
I declare it:
char resultstring[10] = "test";
Then I try to change it:
resultstring[10] = "n";
But Xcode gives me this warning: Warning: assignment makes integer from pointer without a cast
What on earth is that about? Sorry to bother you all but I'm really tearing my hair out over this. I'm sure that this is extremely simple for you all!
Thanks for any help in advance,
David
|
|
|
|
|
|
|
|
|
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status:
Offline
|
|
Two problems (maybe more, but I'll just explain these ):
1. Arrays are zero-indexed. Which means that if you declare an array with a size of 10, appropriate indexes are 0-9.
2. Double quotes signify a string literal (eg "cheese") and their type in C is char*. That's one reason (besides the index) why your assignment fails. "n" is actually a char*, specifically it is something like ['n', '\0'] (note that string literals add the null terminator automatically). If you assign it to an index of your resultstring array, what you're doing is is converting "n" from being a char* into being an integer (which is how chars are represented). Your assignment should be resultstring[x] = 'n' if you're trying to change a character in the string (where x is a legal index), or resultstring = "n" if you're trying ot change the contents entirely.
Hope that helps. I haven't programmed in C in a long while, and it can be strict, so I may have missed something.
(
Last edited by itai195; May 28, 2004 at 02:21 PM.
)
|
|
|
|
|
|
|
|
|
Addicted to MacNN
Join Date: Mar 2000
Location: London, UK
Status:
Offline
|
|
Sorry, what exactly are you trying to do? First you declare resultstring to be a pointer to an array of 10 characters, then you try and assign this pointer to the address of the constant string "test", then you try and assign the 10th character to the address of the constant string "n".
Time to re-read that C book!
const char *resultstring = "test";
resultstring = "n";
Or:
char resultstring[10] = { 't', 'e', 's', 't', 0 };
resultstring[3] = 'n';
Or whatever.
|
|
|
|
|
|
|
|
|
Senior User
Join Date: Sep 2000
Location: UK
Status:
Offline
|
|
Thanks to both of you - that has been a great help.
I had been able to get this to work:
char *resultstring = "test";
However, I was left wondering how large an array this points to - or does this change dynamically, and if so, is there a maximum string length?
Thanks,
David
|
|
|
|
|
|
|
|
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
Originally posted by iMacfan:
I had been able to get this to work:
char *resultstring = "test";
However, I was left wondering how large an array this points to - or does this change dynamically, and if so, is there a maximum string length?
It points to the array of characters {'t', 'e', 's', 't', '\0'}. Therefore, it points to an array of five characters.
One thing you have to understand about C is that there isn't, fundamentally, such a thing as an "array." Data occurs in memory, and if you intentionally allocate a block of data next to each other, you can call that an array, but it isn't fundamentally any different than several unrelated objects that just happen to be allocated next to each other. For instance, if you create an array of five characters, the compiler won't stop you from trying to access the sixth character � because the "array" is just a block of contiguous data, and doesn't know how long it is.
More to the point, the variable resultstring doesn't point to an array � it points to the character 't', which is followed in memory by the rest of the word "test" and the character NUL (represented in C as '\0'). String functions keep accessing the next character in memory until they find NUL, which indicates the end of a string.
(
Last edited by Chuckit; May 28, 2004 at 04:07 PM.
)
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
|
|
|
|
|
|
|
Senior User
Join Date: Sep 2000
Location: UK
Status:
Offline
|
|
Originally posted by Chuckit:
It points to the array of characters {'t', 'e', 's', 't', '\0'}. Therefore, it points to an array of five characters.
Sorry, I wasn't clear. I understand that, but if I then say:
resultstring = "testagain";
Where does the extra memory come from, and am I at risk of crashing the program and computer?
Thanks,
David
|
|
|
|
|
|
|
|
|
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status:
Offline
|
|
Local variables are allocated on the stack. That means you don't really have to worry about memory leaks, but you shouldn't write functions that return a pointer to data allocated in this way because it may be overwritten after the function returns.
|
|
|
|
|
|
|
|
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
Originally posted by iMacfan:
Sorry, I wasn't clear. I understand that, but if I then say:
resultstring = "testagain";
Where does the extra memory come from, and am I at risk of crashing the program and computer?
No. It will then point to another constant string somewhere else in memory that contains the characters {'t', 'e', 's', 't', 'a', 'g', 'a', 'i', 'n', '\0'}. It will not add to the previous string.
Neither resultstring nor any other variable actually contains these letters. They are just free-floating in memory, and your char * contains their address. That's how a pointer works. The size of resultstring remains exactly the same when you assign it; you are just changing it to point to a different place in memory.
Originally posted by itai195:
Local variables are allocated on the stack. That means you don't really have to worry about memory leaks, but you shouldn't write functions that return a pointer to data allocated in this way because it may be overwritten after the function returns.
I'm not exactly sure what this is apropos of, but just to be clear, constant strings are not allocated on the stack. They're in memory throughout the life of your program, so it's safe to return them (but not safe to modify them).
(
Last edited by Chuckit; May 28, 2004 at 06:03 PM.
)
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
|
|
|
|
|
|
|
Senior User
Join Date: Sep 2000
Location: UK
Status:
Offline
|
|
OK, so all I need to do now is find out how to get this pointer allocated to a fixed location of memory, so that I can enter a string into it without adding the letters one by one, and I don't have to worry about the memory being allocated to something else. Is this possible?
Thanks,
David.
P.S. Thank you- this has been very helpful - I honestly do understand most of the concepts in programming, but sometimes I get the wrong end of the stick, and it sure is a very long stick...
|
|
|
|
|
|
|
|
|
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status:
Offline
|
|
Originally posted by Chuckit:
I'm not exactly sure what this is apropos of, but just to be clear, constant strings are not allocated on the stack. They're in memory throughout the life of your program, so it's safe to return them (but not safe to modify them).
Yes, I assumed he wasn't talking about a const because he asked about modifying the string.
|
|
|
|
|
|
|
|
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
Originally posted by iMacfan:
OK, so all I need to do now is find out how to get this pointer allocated to a fixed location of memory, so that I can enter a string into it without adding the letters one by one, and I don't have to worry about the memory being allocated to something else. Is this possible?
If you don't want to assign letters one by one, you can do it one of two ways, both of which involve the function strcpy().
Code:
char test[5];
strcpy(test, "test");
test[0] = 'b'; // Safe because test is on the stack
or
Code:
char *test = malloc(sizeof(char) * 5);
strcpy(test, "test");
test[0] = 'b'; // Safe because test points to memory we've allocated on the heap
free(test);
In the former case, test will be destroyed after the block of code it's in exits. In the latter, it will be destroyed when free() is called.
Incidentally, string-handling should be in any decent introductory C book. You'll want to look into one of those if you want to program C.
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
|
|
|
|
|
|
|
Dedicated MacNNer
Join Date: Sep 2002
Status:
Offline
|
|
If you don't want to assign letters one by one, you can do it one of two ways, both of which involve the function strcpy()
I think that strncpy might be preferable. No point getting people into bad habits.
|
|
|
|
|
|
|
|
|
Senior User
Join Date: Sep 2000
Location: UK
Status:
Offline
|
|
Originally posted by Richard Edgar:
I think that strncpy might be preferable. No point getting people into bad habits.
What is the difference between strncpy and strcpy?
Thanks,
David
|
|
|
|
|
|
|
|
|
Mac Elite
Join Date: Feb 2001
Location: Washington, DC
Status:
Offline
|
|
Originally posted by iMacfan:
What is the difference between strncpy and strcpy?
Thanks,
David
strcpy() will copy all the bytes up to the '\0' then stop.
strncpy() will copy all the bytes up to '\0' then fill the rest of the allocated memory with null chars ('\0').
Say you have a 12 char buffer, and you want to copy a 10 char string into it (including '\0' as part of the string):
strcpy() will copy the 10 chars then stop, leaving the last 2 chars untouched.
It might look like this: {'t', 'e', 's', 't', 'i', 'n', 'g', '1', '2', '\0', 'R', 'c'}
This means you can still access them, or if you have something pointing to them, it will think there's valid data there when there isn't. That's a bad thing.
strncpy() will copy the 10 chars then fill in the next 2 with '\0'.
It will look like this: {'t', 'e', 's', 't', 'i', 'n', 'g', '1', '2', '\0', '\0', '\0'}
This means that any pointer accessing memory after your 10 chars will see a null, not data it can mistake for being valid.
|
/Earth\ Mk\.\ I{2}/
|
|
|
|
|
|
|
|
Dedicated MacNNer
Join Date: Sep 2002
Status:
Offline
|
|
Far more importantly, strncpy won't copy more than n bytes. So, provided you give it the right number, it won't buffer overflow.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Forum Rules
|
|
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
|
|
|
|
|
|