How to use strlen on a structure?

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 2507 Views - Last Post: 20 December 2010 - 11:36 AM Rate Topic: -----

#16 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 19 December 2010 - 05:53 PM

I know this is a C++ program, but since they are nearly similar I thought why not give it a try. I am confused what part of the section were you replying to you, lets just ignore the programme in the past paper but rather the question on using malloc to provide memory for a char * .

I was reading in one text book that we have to use malloc to assign space for a char* , it kinda seems reasonable because if we use array char array[10] or something like that. Or can you give me an example when to use malloc and how to char * inside a structure like the one I just defined.
Was This Post Helpful? 0
  • +
  • -

#17 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1831
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: How to use strlen on a structure?

Posted 19 December 2010 - 07:17 PM

A char* is a variable that can store a memory address. That's all.

You declare a char* just like you declare any other plain old data type: an int or a char, etc. For example:
int i;
char c;
char* cp;

OK. So, being a variable that will store a memory address, on most modern pcs it's either 4 bytes or 8 bytes, depending on whether you have a 32-bit or a 64-bit system. It doesn't have space to store a string -- it only has space to store the address of a memory location where that string is located. The actual string has to be stored in an array of chars.

Now you have a struct that contains a char* as one of its members. As above, say it was declared as:
char* cp;
IF you have a char array already stored someplace in memory, you can assign the address of the first byte of that array to cp, so now cp will "point to" that char array (which, if it ends with a '\0', we call a string). That char array might have been declared like this:
char str[SIZE];
and if so, then you would do this:
cp = str;
to assign the address of str[0] to cp.
(You could also do this:
cp = &str[0];
which is equivalent.)

If you have a really big char array already stored someplace in memory which contains a whole bunch of strings (that's the 'multi-name' example I was describing in post #13), you can even pick some address in the "middle" of that array and assign it to cp. So using the example from post #13, if you had an array called lots_of_names containing 'k' 'i' 'n' 'g' '\0' 'j' 'o' 'h' 'n' '\0' 'l' 'e' 'w' 'i' 's' '\0' 'm' 'a' 'r' 'y' ...
you could do this
cp = &lots_of_names[10];
and then cp would be pointing to the string "lewis".

And you can also do this:
cp = "hello";
Here, "hello" is a string literal, which is just a special kind of char array that the compiler provides for you. It gives you its address and lets you read from that address, but it doesn't allow you to alter the data that it stored there.

If you have none of those things -- no ordinary char array and no string literal -- but you want to make cp point to some new string that you "discover" while the program is running, then you must use malloc to provide memory in which to store that string. So you do this:
cp = malloc( length * sizeof(char) );
where length is at least 1 more than the number of characters in the new string, and then you can use strcpy to copy the new string to that new memory space by writing
strcpy( cp, source_address );

Does that clear things up?

This post has been edited by r.stiltskin: 19 December 2010 - 07:26 PM

Was This Post Helpful? 1
  • +
  • -

#18 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 19 December 2010 - 09:23 PM

View Postr.stiltskin, on 19 December 2010 - 06:17 PM, said:

A char* is a variable that can store a memory address. That's all.

You declare a char* just like you declare any other plain old data type: an int or a char, etc. For example:
int i;
char c;
char* cp;

OK. So, being a variable that will store a memory address, on most modern pcs it's either 4 bytes or 8 bytes, depending on whether you have a 32-bit or a 64-bit system. It doesn't have space to store a string -- it only has space to store the address of a memory location where that string is located. The actual string has to be stored in an array of chars.

Now you have a struct that contains a char* as one of its members. As above, say it was declared as:
char* cp;
IF you have a char array already stored someplace in memory, you can assign the address of the first byte of that array to cp, so now cp will "point to" that char array (which, if it ends with a '\0', we call a string). That char array might have been declared like this:
char str[SIZE];
and if so, then you would do this:
cp = str;
to assign the address of str[0] to cp.
(You could also do this:
cp = &str[0];
which is equivalent.)

If you have a really big char array already stored someplace in memory which contains a whole bunch of strings (that's the 'multi-name' example I was describing in post #13), you can even pick some address in the "middle" of that array and assign it to cp. So using the example from post #13, if you had an array called lots_of_names containing 'k' 'i' 'n' 'g' '\0' 'j' 'o' 'h' 'n' '\0' 'l' 'e' 'w' 'i' 's' '\0' 'm' 'a' 'r' 'y' ...
you could do this
cp = &lots_of_names[10];
and then cp would be pointing to the string "lewis".

And you can also do this:
cp = "hello";
Here, "hello" is a string literal, which is just a special kind of char array that the compiler provides for you. It gives you its address and lets you read from that address, but it doesn't allow you to alter the data that it stored there.

If you have none of those things -- no ordinary char array and no string literal -- but you want to make cp point to some new string that you "discover" while the program is running, then you must use malloc to provide memory in which to store that string. So you do this:
cp = malloc( length * sizeof(char) );
where length is at least 1 more than the number of characters in the new string, and then you can use strcpy to copy the new string to that new memory space by writing
strcpy( cp, source_address );

Does that clear things up?

Yes it kinda does thanks alot :D . So the end of the answere is that you cant change a string that is pointed by char * in any way like just change one character in the string. Is there any function in stdlib that gives us this ability.


I took this code from another post here
/*
 * Yet another method to reverse a string
 * Author: Danny Battison
 * Contact: gabehabe@gmail.com
 */

#include <stdio.h>
#include <string.h>

char* reverseCharArray(char str[], int pos) {   ]// can I replace (char *str,int pos)
    int swap = (strlen(str)-1) - pos;

    if (swap < pos) {
        char temp = str[swap];  // what will happen to these then ? 
        str[swap] = str[pos];
        str[pos] = temp;
        return reverseCharArray(str, --pos);
    } else {
        return str;
    }
}

/** EXAMPLE USAGE **/
int main() {
    char str[] = "gabehabe is so freakin' awesome.";
    // remember, because an array is 0 based, we have to pass the length-1
    printf(reverseCharArray(str, strlen(str)-1));
    return 0;
}

This post has been edited by micaxxa: 19 December 2010 - 09:32 PM

Was This Post Helpful? 0
  • +
  • -

#19 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1831
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: How to use strlen on a structure?

Posted 19 December 2010 - 10:55 PM

View Postmicaxxa, on 19 December 2010 - 11:23 PM, said:

Yes it kinda does thanks alot :D . So the end of the answere is that you cant change a string that is pointed by char * in any way like just change one character in the string.

No! That's not what I said. You can't change characters in a STRING LITERAL. You can change characters in a char array. It doesn't matter whether it is pointed to by a char* or not.

Look:
char* pointer1 = "I love";
char arr[10] = "finals";
char* pointer2 = arr;
strcpy( pointer2, "beer" );  // this is perfectly legal
*(pointer2 + 3) = 's';             // this is also legal
strcpy( pointer1, "I hate" );  // this is not
*(pointer1 + 2) = 'L';         // nor this


Even though "finals" looks like a string literal, when the array arr is initialized, the characters 'f' 'i' 'n' 'a' 'l' 's' '\0' are stored in the array, which is NOT a string literal so it can be modified. But when "I love" is assigned to pointer1, what's actually happening is that the address of the string literal "I love" is being stored in pointer1. The compiler is "in charge" of the memory where "I love" is actually stored and you can't alter anything in that area of memory.

This post has been edited by r.stiltskin: 19 December 2010 - 11:05 PM

Was This Post Helpful? 0
  • +
  • -

#20 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 20 December 2010 - 04:33 AM

View Postr.stiltskin, on 19 December 2010 - 09:55 PM, said:

View Postmicaxxa, on 19 December 2010 - 11:23 PM, said:

Yes it kinda does thanks alot :D . So the end of the answere is that you cant change a string that is pointed by char * in any way like just change one character in the string.

No! That's not what I said. You can't change characters in a STRING LITERAL. You can change characters in a char array. It doesn't matter whether it is pointed to by a char* or not.

Look:
char* pointer1 = "I love";
char arr[10] = "finals";
char* pointer2 = arr;
strcpy( pointer2, "beer" );  // this is perfectly legal
*(pointer2 + 3) = 's';             // this is also legal
strcpy( pointer1, "I hate" );  // this is not
*(pointer1 + 2) = 'L';         // nor this


Even though "finals" looks like a string literal, when the array arr is initialized, the characters 'f' 'i' 'n' 'a' 'l' 's' '\0' are stored in the array, which is NOT a string literal so it can be modified. But when "I love" is assigned to pointer1, what's actually happening is that the address of the string literal "I love" is being stored in pointer1. The compiler is "in charge" of the memory where "I love" is actually stored and you can't alter anything in that area of memory.



Can we use malloc here by any chance? LOL.
Was This Post Helpful? 0
  • +
  • -

#21 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1831
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: How to use strlen on a structure?

Posted 20 December 2010 - 07:28 AM

View Postmicaxxa, on 20 December 2010 - 06:33 AM, said:

Can we use malloc here by any chance? LOL.


Sure. Like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *pointer1 = "happy"; // here pointer1 doesn't "own" any memory, it just points to a string literal
    printf("%s\n", pointer1);  // we can print it, but we can't change what's stored there
                               // but we can change the address that it points to
    pointer1 = malloc( 10 * sizeof(char) );  // now pointer 1 points to an allocated block of memory
                                             // and we can do whatever we want with it,
                                             // as long as we don't exceed its bounds
    strcpy(pointer1, "brain");
    printf("%s\n", pointer1);
    *pointer1 = 'd';
    printf("%s\n", pointer1);
    return 0;
}


Was This Post Helpful? 1
  • +
  • -

#22 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 20 December 2010 - 09:27 AM

View Postr.stiltskin, on 20 December 2010 - 06:28 AM, said:

View Postmicaxxa, on 20 December 2010 - 06:33 AM, said:

Can we use malloc here by any chance? LOL.


Sure. Like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *pointer1 = "happy"; // here pointer1 doesn't "own" any memory, it just points to a string literal
    printf("%s\n", pointer1);  // we can print it, but we can't change what's stored there
                               // but we can change the address that it points to
    pointer1 = malloc( 10 * sizeof(char) );  // now pointer 1 points to an allocated block of memory
                                             // and we can do whatever we want with it,
                                             // as long as we don't exceed its bounds
    strcpy(pointer1, "brain");
    printf("%s\n", pointer1);
    *pointer1 = 'd';
    printf("%s\n", pointer1);
    return 0;
}




Thankyou so much, most of my confusion has cleared now, ahhh thankyou so much for your time and response.
I hope to be a good programmer like you one day and help others too .
Also if any confused person like me is reading this post , should see this http://www.linuxques...-struct-337291/


This was also one of my question, allocating space for a char * when making a new node
Do you think the way the guy did it like is correct ? and do we have to do it this way if we dont use char ?

typedef struct{
char *name;
int age;
char *address;
}person;


struct person * alloc_person(const char *name, const char *address, int age)
{
   struct person *p = malloc(sizeof(struct person));

   p->name = calloc(strlen(name) + 1, 1); /* sizeof(char) is always 1 */
   p->address = calloc(strlen(address) + 1, 1);

   strcpy(p->name, name);
   strcpy(p->address, address);

   p->age = age;

   return p;
}

This post has been edited by micaxxa: 20 December 2010 - 09:29 AM

Was This Post Helpful? 0
  • +
  • -

#23 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 20 December 2010 - 09:50 AM

Why is that you didnt require dereferencing the char pointer when printing the strings,

although when its an int pointer we have to deference it to check the contents of the int of the address stored in it ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {

      int m;
  int *k;
  m=3;

  k=&m;
  printf("%d \n",*k); // why did we require derefencing here and not the pointer when printing ? 

    char *pointer1 = "happy"; // here pointer1 doesn't "own" any memory, it just points to a string literal
    printf("%s\n", pointer1);  // we can print it, but we can't change what's stored there
                               // but we can change the address that it points to
    pointer1 = malloc( 10 * sizeof(char) );  // now pointer 1 points to an allocated block of memory
                                             // and we can do whatever we want with it,
                                             // as long as we don't exceed its bounds
    strcpy(pointer1, "brain");
    printf("%s\n", pointer1);
    pointer1[1] = 'd';
    printf("%s\n", pointer1);
    return 0;
}


Was This Post Helpful? 0
  • +
  • -

#24 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1831
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: How to use strlen on a structure?

Posted 20 December 2010 - 10:19 AM

The allocations are correct in that example, but the struct syntax is not. That structure has no tag
(e.g.: typedef struct person { // bla bla };
but he did use a typedef:
(e.g.: typedef struct { // bla bla } person;
which is fine, but thereafter he should refer to it as just "person", not "struct person".

Like this:
person * alloc_person(const char *name, const char *address, int age)
{
    person *p = malloc(sizeof(person));

    p->name = calloc(strlen(name) + 1, 1)
    p->address = calloc(strlen(address) + 1, 1);

    strcpy(p->name, name);
    strcpy(p->address, address);

    p->age = age;

    return p;
}



And yes, this is how you have to do it unless you defined name and address as arrays big enough to hold any name or address, for example:
typedef struct{
    char name[100];
    int age;
    char address[100];
}person;

or whatever size is appropriate for your application.

View Postmicaxxa, on 20 December 2010 - 11:50 AM, said:

Why is that you didnt require dereferencing the char pointer when printing the strings,

although when its an int pointer we have to deference it to check the contents of the int of the address stored in it ?


Just "because". :)

For %d or %c or %f you have to give printf an int or a char or a float (or double), but for %s you have to give printf a pointer to a char. That's just the way printf works.
Was This Post Helpful? 0
  • +
  • -

#25 micaxxa  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 51
  • Joined: 17-October 10

Re: How to use strlen on a structure?

Posted 20 December 2010 - 11:36 AM

LOL. Okay I am still experimenting with the notation trying out with double pointers and stuff.

This post has been edited by micaxxa: 20 December 2010 - 11:48 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2