Search FAQ

Gammon Forum

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

use of char and pointers

Posting of new messages is disabled at present.

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,
type var[x]
, 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,589 views.

Posting of new messages is disabled at present.

Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.