Page 1 of 1

Char *

Posted: Mon Nov 02, 2009 8:50 pm
by _ross_
In C/C++, I use char * to define a string. Why is it not OK to use a character array in your operating system, when its fine for a normal program, and also, how does the compiler set where a char * oints too when you make it?
I believe there is something important I don't know here.....

Re: Char *

Posted: Mon Nov 02, 2009 10:19 pm
by xixpsychoxix
the major problem that i see with using a char * as a string in an os is this:

Code: Select all


char *string = "Hello", *copy;

while (*string++ == *copy++)
 ;

You would expect this code to copy string into copy, but the problem is that copy is unallocated, meaning that it is completely unsafe to use it the way it is. You are writing to a pointer in memory and since the operating system has not made sure that this area is safe to write to, you could be overwriting something vital, code or data of some sort. of course this problem is solved as such:

Code: Select all


char string[6] = "Hello", copy[6];
int i = 0;

while ((copy[i++] == string[i++]) != 0)
 ;

Besides this example there are various other aspects of pointers that make them very dangerous to use if the operating system cannot manage the memory in use. if functions such as malloc were implemented in your system pointers would be much safer. As for how your compiler determines where to place your pointer, I'm not sure. I would imagine that it is compiler-dependent, but you can also force a pointer to point to a certain area by casting an integer to a char * as such:

Code: Select all


char *video_mem = (char *) 0xb80000;



I hope that this answers your question and i am quite sorry for wasting your time if i misunderstood the whole point of the question.

Re: Char *

Posted: Tue Nov 03, 2009 4:18 am
by djsilence
If I remember char * - it is simple array of characters, string defined by it goes to first '\0'; You can use it like a simple array anywhere (but in C/C++). Can you post some code, that works in your program and doesn't work with os.

Where char * points to at the begining - depends on compiler... But almost any compiler after 1996 year destribution do next:

1. if you just put: char * str; then str will point to 0.
2. if you put char * str = (char *)0x100; the str point to 0x100. this mean that your string is any character between 0x100 including and the nearest 0x00 character.
3. if you put char * str = "hello"; in this case compiler store the value of string in data section, and the str points to that value.

Hope it help. Daniel.

Re: Char *

Posted: Tue Nov 03, 2009 11:41 am
by Andyhhp
Why is it not OK to use a character array in your operating system
Why are you under the impression its not ok to use a character array?

Re: Char *

Posted: Tue Nov 03, 2009 5:05 pm
by _ross_
A post on OSDev. Pointer to null terminated string. It said you need to have malloc first, but C doesn't use malloc if you do
char * test;
test = "test";

Does it?

Code: Select all

int findfile (char *fname)
{
   unsigned short entry = 1;
   char *testfname;
   DebugPrintf("\nLooking for file: %s\n\n", fname);
   while (true)
   {
      for(int i=0; i<11; i++)
         testfname[i] = RootDir_MemLocation[(32 * (entry-1)) + i]; // where does testfname point?
The above occurs everywhere throughout your code. Along with code like:
From OSDev

Re: Char *

Posted: Tue Nov 03, 2009 8:48 pm
by xixpsychoxix
well the point isnt that it's unsafe to use pointers, just pointers that are unallocated. that means that when you declare something like:

char a[10];

the compiler will then set aside ten free bytes for this array. but if you declare something like:

char *a;

the compiler will only allocate a pointer, that is a variable that holds an address. that means that a points to some point in memory that the compiler decides to put it. this could be anywhere vital, which is the reason it is so unsafe. if the pointer points to code, data, whatever, the compiler is not picky, it will let you write to that address whenever you feel like. but if you use a function like malloc() to get a pointer to a portion of memory that is OK to write to there is no problem. also, pointers and arrays are sort of interchangeable, so you could write something like:

Code: Select all


char a[10];

*a++ = 'Y';

and now a[1] contains the letter Y. However, i have found that freely mixing the two often leads me to problems and compiler errors so be careful and make sure you know what you are doing there. as for your question, malloc is never actually called unless you call it, so while this is correct:

char *hello = "Hello, world!";

this is not:

char *hello;
hello = "Hello, world!";

because in the first example the compiler will set aside the required space for the string and put it in the program at a certain point which it will then set the pointer value to. so if the compiler placed the string at address 0x1000, that is then where the pointer would be pointing to.


Sorry guys i like to ramble alot!!! I'll try to make it more short and sweet next time!

Re: Char *

Posted: Wed Nov 04, 2009 5:13 am
by Mike
Hello,

I think I know what post you are referring to (and I think I replied to it myself.) The problem with that code is not the fact that he is using a char pointer but rather that he was using a wild pointer, which can point to anything. Code that has wild pointers are guaranteed to cause problems. (In your particular code snippet, testfname is a wild pointer - it has not been initialized so testfname = 0 overwrites some unknown location in memory.)

Re: Char *

Posted: Thu Nov 05, 2009 5:11 pm
by _ross_
Oh, thanks!
So, if he did testfname = " "; above that code, its fine?
If so, I now understand :)!

Re: Char *

Posted: Fri Nov 06, 2009 4:37 pm
by xixpsychoxix
No, really it isnt because there is still not enough space allocated for the whole 11-byte filename. the compiler in this case will just put a null character (\0) in memory and then give you a pointer to it. That does not, however, mean that the bytes following it are not some other data or code. they are more than likely data, but you still dont want to write over them. because the pointer still does not point to a block of memory specifically reserved for it's use it will most likely cause a problem. simply adding the quotes does not sufficiently allocate the memory that you are looking for. you must either specify the size of the string like so: 'char a[10]', or you must have a routine that can allocate that space for you safely: 'char *a = malloc (10)', otherwise you are headed for trouble.

Re: Char *

Posted: Fri Nov 06, 2009 7:12 pm
by _ross_
But, if the code checked for null, its fine though?

Re: Char *

Posted: Sat Nov 07, 2009 12:02 am
by xixpsychoxix
Im not really sure what you mean there. If you mean that if your code checked to see if the value pointed to was null you could do whatever you feel like with the pointer with no ill effects im afraid that this is incorrect. Actually it is pretty much unsafe to do what you are trying to do at all due to the fact that the pointer is most likely pointing to a random place in memory. It's kinda like this:

Code: Select all


Memory Address:

Location:   Data:
--------------------
0000:        0x01    ;this is your pointer *p pointing to memory location 1
0001:        0x00   ;and this is the location your pointer points to
0002:        0xB4    ;this is part of an opcode
0003:        0x02    ;and this is the other part

Looking at this, even though you declared p as:

Code: Select all

char *p = "";
and the compiler told p to point to memory address 2 by default you do not have an allocated string, rather p simply points to a null char in memory wherever the compiler chose to place it.

so if you start messing with p, say you tried this:

Code: Select all

*p++ = 0xB5;
since p initially points to the byte at memory address 1 and you increment it in this operation, you will effectively overwrite the machine instruction at memory location 2!!! not a good side effect. basically a pointer is just an integer that holds a memory address number. it can point anywhere and is VERY dangerous if it is not used in the proper way.

a char pointer initialized with a string in that way is just simply a way to place strings in memory. it will only allocate enough memory for the string plus the null character, the same as if you declared it as an array:

Code: Select all


char *p   = "Hello";        //these are essentially the same declaration
char p[6] = "Hello";       //either way p will point to a six-byte area of 'safe' memory

This is where things like array bounds come into play. If the programmer does not pay careful attention to the way that pointers are used it is very easy to become trapped in pointer issues. to tell you the truth the best thing to do would be to either get hold of a good c reference and read about pointers or do a google search for pointers in c and see what you can come up with. pointers gave me alot of trouble at first too because of the very reason that you mentioned. i thought that i could just declare them like so:

Code: Select all

char *file = "";
and then use them how i wanted. that gave me alot of major headaches at first, and i poured over books and internet sites about pointers until i understood almost everything about them.
Again i find myself babbling... i like to talk alot guys sorry!!!

Re: Char *

Posted: Sun Nov 08, 2009 10:24 am
by _ross_
xixpsychoxix wrote:Im not really sure what you mean there. If you mean that if your code checked to see if the value pointed to was null you could do whatever you feel like with the pointer with no ill effects im afraid that this is incorrect. Actually it is pretty much unsafe to do what you are trying to do at all due to the fact that the pointer is most likely pointing to a random place in memory. It's kinda like this:

Code: Select all


Memory Address:

Location:   Data:
--------------------
0000:        0x01    ;this is your pointer *p pointing to memory location 1
0001:        0x00   ;and this is the location your pointer points to
0002:        0xB4    ;this is part of an opcode
0003:        0x02    ;and this is the other part

Looking at this, even though you declared p as:

Code: Select all

char *p = "";
and the compiler told p to point to memory address 2 by default you do not have an allocated string, rather p simply points to a null char in memory wherever the compiler chose to place it.

so if you start messing with p, say you tried this:

Code: Select all

*p++ = 0xB5;
since p initially points to the byte at memory address 1 and you increment it in this operation, you will effectively overwrite the machine instruction at memory location 2!!! not a good side effect. basically a pointer is just an integer that holds a memory address number. it can point anywhere and is VERY dangerous if it is not used in the proper way.

a char pointer initialized with a string in that way is just simply a way to place strings in memory. it will only allocate enough memory for the string plus the null character, the same as if you declared it as an array:

Code: Select all


char *p   = "Hello";        //these are essentially the same declaration
char p[6] = "Hello";       //either way p will point to a six-byte area of 'safe' memory

This is where things like array bounds come into play. If the programmer does not pay careful attention to the way that pointers are used it is very easy to become trapped in pointer issues. to tell you the truth the best thing to do would be to either get hold of a good c reference and read about pointers or do a google search for pointers in c and see what you can come up with. pointers gave me alot of trouble at first too because of the very reason that you mentioned. i thought that i could just declare them like so:

Code: Select all

char *file = "";
and then use them how i wanted. that gave me alot of major headaches at first, and i poured over books and internet sites about pointers until i understood almost everything about them.
Again i find myself babbling... i like to talk alot guys sorry!!!
Sorry, I meant if the code was for C string handling, so it stopped on reaching a null.
Thanks anyway!