Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Entire forum
➜ SMAUG
➜ SMAUG coding
➜ use of char and pointers
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Gohan_TheDragonball
USA (183 posts) Bio
|
Date
| Wed 10 Aug 2005 02:49 AM (UTC) Amended on Wed 10 Aug 2005 03:30 AM (UTC) by Gohan_TheDragonball
|
Message
| I am doing some work with something, and I am trying to
get into using char arrays. however i am kind of just
winging it, and could use some help with how to do certain
things, as i keep getting warnings from my compiler.
the variable:
char **ranks[5];
usage:
fprintf( fp, "Ranks '%s' '%s' '%s' '%s' '%s'\n",
clan->ranks[0], clan->ranks[1],
clan->ranks[2], clan->ranks[3], clan->ranks[4] );
error from compiler:
clans.c:229: warning: char format, pointer arg (arg 3)
clans.c:229: warning: char format, pointer arg (arg 4)
clans.c:229: warning: char format, pointer arg (arg 5)
clans.c:229: warning: char format, pointer arg (arg 6)
clans.c:229: warning: char format, pointer arg (arg 7)
usage:
for ( i = 0; i < 5; i++ )
{
if (!clan->ranks)
clan->ranks = STRALLOC( "" );
}
error from compiler:
clans.c:472: warning: assignment from incompatible pointer type
usage:
ch_printf( ch, "\n\r&zMembers and Ranks:\n\r&W 1.) %s (%s)\n\r 2.) %s (%s)\n\r 3.) %s (%s)\n\r 4.) %s (%s)\n\r 5.) %s (%s)\n\r",
clan->positions[0][0] != '\0' ? clan->positions[0] : "Open", clan->ranks[0][0] != '\0' ? clan->ranks[0] : "",
clan->positions[1][0] != '\0' ? clan->positions[1] : "Open", clan->ranks[1][0] != '\0' ? clan->ranks[1] : "",
clan->positions[2][0] != '\0' ? clan->positions[2] : "Open", clan->ranks[2][0] != '\0' ? clan->ranks[2] : "",
clan->positions[3][0] != '\0' ? clan->positions[3] : "Open", clan->ranks[3][0] != '\0' ? clan->ranks[3] : "",
clan->positions[4][0] != '\0' ? clan->positions[4] : "Open", clan->ranks[4][0] != '\0' ? clan->ranks[4] : "" );
error from compiler:
clans.c:2681: warning: pointer type mismatch in conditional expression
any help in getting rid of these, what to change etc?
thanks
<edit>
on a side note, i am getting very wierd memory leaks, the names are not being read in properly, i am guessing it has to do with the warnings. | Top |
|
Posted by
| Greven
Canada (835 posts) Bio
|
Date
| Reply #1 on Wed 10 Aug 2005 04:41 AM (UTC) Amended on Wed 10 Aug 2005 11:12 AM (UTC) by Greven
|
Message
| There are a few things that you should know about pointer arrays:
char **ranks[5];
Is a 5 element array of pointers to character pointers. Based on what your doing with the variable in the code, you probably want:
char *ranks[5];
This is a 5 element array of character pointers. Since most strings in c are handled through pointers to the beginning of an array of characters.
fprintf( fp, "Ranks '%s' '%s' '%s' '%s' '%s'\n",
clan->ranks[0], clan->ranks[1],
clan->ranks[2], clan->ranks[3], clan->ranks[4] );
Since arrays are passed via pointers into functions, fprintf is expecting the arguements being supplied to be of type "character pointer" when they are actually "pointer pointers". Thats why that error.
for ( i = 0; i < 5; i++ )
{
if (!clan->ranks)
clan->ranks = STRALLOC( "" );
}
This actually has a seperate issue: clan->ranks is an array of pointers to character pointers. You are trying to assign a pointer to a character into it, and they are of different types. If you correct the variable declaration, then you actually need:
for ( i = 0; i < 5; i++ )
{
if (!clan->ranks)
clan->ranks[i] = STRALLOC( "" );
}
For your third error, correcting the variable type should fix this error as well.
Hope that helps and that I'm not smoking something and misunderstood you.
EDIT
Heh, correction as pointed out by Ksilyan |
Nobody ever expects the spanish inquisition!
darkwarriors.net:4848
http://darkwarriors.net | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #2 on Wed 10 Aug 2005 07:12 AM (UTC) |
Message
| You guys need to make sure you escape the [i] in your code since it's making everything go italic and nothing makes sense anymore. :-) The missing [i] makes things look wrong - Greven, I think you were correcting his 'mistake' when his second mistake was also due to the typing error (char**[5] instead of char*[5]) - except that the [i] got lost as italics. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Greven
Canada (835 posts) Bio
|
Date
| Reply #3 on Wed 10 Aug 2005 11:50 AM (UTC) |
Message
|
Quote: Greven, I think you were correcting his 'mistake' when his second mistake was also due to the typing error (char**[5] instead of char*[5]) Maybe I'm misunderstanding you, but are you saying that the extra asterik was a typo? If you are, how does that account for the compile warnings that he is getting? I'm going on 4 hours of mud sleep(slouched over in the compute chair) so I may be missing something. |
Nobody ever expects the spanish inquisition!
darkwarriors.net:4848
http://darkwarriors.net | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #4 on Wed 10 Aug 2005 04:48 PM (UTC) |
Message
| Nono, the second asterisk indeed should not be there, I was just talking about when he wrote: for ( i = 0; i < 5; i++ )
{
if (!clan->ranks)
clan->ranks = STRALLOC( "" );
}
In his original text, it goes italic after 'ranks' which means he put in a [i] but forgot to escape it. So I think it would in fact have been a correct line of code, if he hadn't had two asterisks on his type. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Gohan_TheDragonball
USA (183 posts) Bio
|
Date
| Reply #5 on Wed 10 Aug 2005 11:26 PM (UTC) |
Message
| hey great, i think i got confused when i did that. i thought that if you put char *ranks[5] it would only let that variable have 5 characters. thanks for the help, just also to point out i had to do the following to get rid of some memory errors.
changed:
for ( i = 0; i < 5; i++ )
{
clan->ranks[i] = fread_word(fp);
}
to:
for ( i = 0; i < 5; i++ )
{
clan->ranks[i] = STRALLOC(fread_word(fp));
}
| Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #6 on Wed 10 Aug 2005 11:34 PM (UTC) |
Message
| When you have, in C,, it means "give me an array with x elements of type 'type'." That's why here, char*ranks[5] gives an array of 5 char*.
(C++ plug: this is less headache-prone with STL strings!) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Gohan_TheDragonball
USA (183 posts) Bio
|
Date
| Reply #7 on Wed 10 Aug 2005 11:38 PM (UTC) |
Message
| well the reason i got confused was because of the following you find in most mud source codes.
char arg[MAX_STRING_LENGTH];
what would the difference be between char *arg and char arg[MAX_STRING_LENGTH]. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #8 on Thu 11 Aug 2005 12:49 AM (UTC) |
Message
| char arg[x] means an array of x chars. Recalling that an array is really a pointer, that is why char * arg and char arg[x] both yield a string - which is in turn nothing more than a sequence of characters starting at the first byte of the pointer and going until the first null character (\0).
The difference between char * and char[] is that the pointer has no memory allocated on the stack, whereas the array of characters will be allocated on the stack. So, you can write:char arg[100]; arg[2] = 'a';
It is however not a good idea to write:char * arg; arg[2] = 'a';
This is not a good idea because arg is just a pointer and doesn't point to anything (yet, at least).
The key point here is that an array in C is really just a pointer to a block of memory. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Gohan_TheDragonball
USA (183 posts) Bio
|
Date
| Reply #9 on Thu 11 Aug 2005 05:58 AM (UTC) |
Message
| just one more quick question:
would i do an if check like this?
if ( clan->ranks[0][0] != '\0' ) | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #10 on Thu 11 Aug 2005 06:42 AM (UTC) |
Message
| That depends. It's always ok to do ranks[0,1,2,3,4] if ranks is defined as a char*[5]. This merely gives you a pointer. Whether or not it is legal to take another subscript depends on whether or not there is actually a string allocated at that location. See:void bad()
{
char * strings[2];
strings[0][0] = 'a'; // boom
}
void good()
{
char * strings[2];
// allocate memory for the strings
// (you probably don't see malloc a lot in SMAUG ... it has its own way of allocating strings (in the hash table and otherwise)
for ( int i = 0; i < 2; i++ )
strings[i] = (char*) malloc( STR_SIZE );
// now we can set the value
strings[0][0] = 'a'; // ok
}
|
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Raz
(32 posts) Bio
|
Date
| Reply #11 on Thu 11 Aug 2005 02:38 PM (UTC) |
Message
|
Quote: Recalling that an array is really a pointer. . .
No. An array is not a pointer. An array can decay into a pointer, but it does not act like a pointer.
Quote: The key point here is that an array in C is really just a pointer to a block of memory.
The only time that arrays and pointers act the same in C is when you are passing them to functions, and that is only because of convience. Pointers and arrays do different things, have different types, access their elements differently, etc. Assuming that an array is a pointer is a very bad assumption. |
-Raz
C++ Wiki: http://danday.homelinux.org/dan/cppwiki/index.php | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #12 on Thu 11 Aug 2005 03:40 PM (UTC) Amended on Thu 11 Aug 2005 03:41 PM (UTC) by David Haley
|
Message
| Of course arrays are basically pointers - they're pointers with a few additional properties but indexing into an array is basically the same as indexing into a pointer. I'd be curious to hear what "very different things" arrays and pointers do, except for what I've already outlined about being allocated, and the additional (small) details about not being able to e.g. make an array 'point' somewhere else. If you wouldn't mind explaining yourself instead of making a one-or-two line comment, I'd appreciate it... :) (statements on their own are nearly useless)
EDIT:
By the way, it seems awfully interesting that the entire concept of strings in C depends on the 'mere convenience' of arrays acting as pointers when passed to functions. Again, I'd like to hear your explanation as to why these are so incredibly different. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Raz
(32 posts) Bio
|
Date
| Reply #13 on Thu 11 Aug 2005 11:32 PM (UTC) |
Message
|
Quote: If you wouldn't mind explaining yourself instead of making a one-or-two line comment, I'd appreciate it... :) (statements on their own are nearly useless)
Sure thing. Tell me if I need to clarify anything since this is quite a large subject (amazingly enough).
Quote: (arrays) they're pointers with a few additional properties but indexing into an array is basically the same as indexing into a pointer.
Let me being my argument by referring to the most basic fact - the ISO/ANSI C standard specifically distinguishes arrays and pointers as two seperate types. It constantly refers to them as seperate types.
Now, indexing into an array is definately *not* the same as indexing into a pointer. The compiler sees both types differently. Lets assume we have an array a[5] and a pointer p. Let us say we wanted to access index 3 of both objects. For "a", the compiler would emit code to begin at the location of a, move past it 3 objects, and get the value. For "p", the compiler must start at location of p, get the pointed object, start again at the pointer object's location, move three past, and then it finally ends up at the desired element. Clearly the indexing of both arrays and pointers are not the same.
(Reference:http://www.eskimo.com/~scs/C-faq/q6.2.html)
(I slightly stole my example from the FAQ ;).)
Quote: I'd be curious to hear what "very different things" arrays and pointers do, except for what I've already outlined about being allocated, and the additional (small) details about not being able to e.g. make an array 'point' somewhere else.
"small details"? Let me just list what I can think of when arrays cannot act like pointers:
-If you had a global variable "char array[10]", you could not reference it in another translation unit by saying "extern char *array;"
-Like you said, an array is not a modifiable lvalue.
-Arrays cannot be truly assigned to a pointer of a pointer (it will compile, but the types are incompatable). Ex:
void f(char **p) { }
int main( void )
{
char *p;
char ar[5];
f(&p);//OK
f(&ar);//Incompatable types
}
-You cannot have an array of a function.
-You cannot have an array of an incomplete type.
-sizeof of an array will yield a very different result
Basically, this is all that I can think of off the top of my head. Like I said before, an array is not a pointer but it can decay into a pointer of the same type.
Quote: By the way, it seems awfully interesting that the entire concept of strings in C depends on the 'mere convenience' of arrays acting as pointers when passed to functions. Again, I'd like to hear your explanation as to why these are so incredibly different.
I fail to understand for what you are asking. I don't understand what you mean by "the entire concept of strings in C". String literals are considered "special" (as per the standard) when it comes to assigning them to arrays, if that answers any questions that you were implying.
|
-Raz
C++ Wiki: http://danday.homelinux.org/dan/cppwiki/index.php | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #14 on Thu 11 Aug 2005 11:56 PM (UTC) Amended on Fri 12 Aug 2005 12:00 AM (UTC) by David Haley
|
Message
| I think the source of confusion is really quite simple. You are taking the language implementor's perspective and I am taking the programmer's perspective. (I thought that would be obvious since I was talking amongst programmers and explaining programming, not compilers, but I guess I wasn't clear enough.)
Obviously, what you say is true from the compiler's perspective, but is almost irrelevant from the programmer's perspective - especially when the programmer in question is a novice just learning SMAUG. To take an analogy, my impression of your reaction is the one I would have of somebody who got pedantic about relativity etc. if I were explaining physics to a novice using only Newtonian concepts. Not only are the relativistic concepts almost irrelevant at that point in the student's learning, but they're also confusing and distracting.
In any case, as far as the programmer is concerned, except for a few small details, arrays and pointers are in fact extremely similar. (Yes, I really did mean "small details"... the cases in which things break are rare and, arguably, usually indicative of bad style to begin with. sizeof is perhaps the exception here.)
EDIT:
Another note of clarification: in addition to the confusion of perspective, there also seems to be a slight confusion regarding what 'array' means. I think you are using it as the whole array of objects; I am using 'array' as referring to the name of the array. I think that this and the other confusion are why we aren't talking the same language and aren't agreeing with each other. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
36,443 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top