Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Total Newbie using C

Total Newbie using C
Thread Tools
iMacfan
Senior User
Join Date: Sep 2000
Location: UK
Status: Offline
Reply With Quote
May 28, 2004, 01:53 PM
 
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
     
itai195
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status: Offline
Reply With Quote
May 28, 2004, 02:11 PM
 
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. )
     
Angus_D
Addicted to MacNN
Join Date: Mar 2000
Location: London, UK
Status: Offline
Reply With Quote
May 28, 2004, 02:13 PM
 
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.
     
iMacfan  (op)
Senior User
Join Date: Sep 2000
Location: UK
Status: Offline
Reply With Quote
May 28, 2004, 03:09 PM
 
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
     
Chuckit
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status: Offline
Reply With Quote
May 28, 2004, 03:54 PM
 
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'."
     
iMacfan  (op)
Senior User
Join Date: Sep 2000
Location: UK
Status: Offline
Reply With Quote
May 28, 2004, 05:13 PM
 
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
     
itai195
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status: Offline
Reply With Quote
May 28, 2004, 05:40 PM
 
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.
     
Chuckit
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status: Offline
Reply With Quote
May 28, 2004, 05:48 PM
 
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'."
     
iMacfan  (op)
Senior User
Join Date: Sep 2000
Location: UK
Status: Offline
Reply With Quote
May 28, 2004, 06:08 PM
 
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...
     
itai195
Addicted to MacNN
Join Date: May 2001
Location: Cupertino, CA
Status: Offline
Reply With Quote
May 28, 2004, 06:20 PM
 
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.
     
Chuckit
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status: Offline
Reply With Quote
May 28, 2004, 06:22 PM
 
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'."
     
Richard Edgar
Dedicated MacNNer
Join Date: Sep 2002
Status: Offline
Reply With Quote
May 29, 2004, 10:23 AM
 
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.
     
iMacfan  (op)
Senior User
Join Date: Sep 2000
Location: UK
Status: Offline
Reply With Quote
May 29, 2004, 02:03 PM
 
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
     
Earth Mk. II
Mac Elite
Join Date: Feb 2001
Location: Washington, DC
Status: Offline
Reply With Quote
May 29, 2004, 06:53 PM
 
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}/
     
Richard Edgar
Dedicated MacNNer
Join Date: Sep 2002
Status: Offline
Reply With Quote
May 30, 2004, 09:58 AM
 
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 Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 01:08 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,