need explanation about string in C

kapot
kapot used Ask the Experts™
on
Hi,
I am just new in C, and I have difficulties understanding string in C.

Suppose I define pointer to string like this :

   char *str;

Then, I can assign it like this :

   str = "this is a string";

Is that assignment also allocating a memory pointed by str?

I meant, what happen if after that I reassign str with shorter string?

   str = "this";

Reallocated?

Should I care with allocation of memory?

Because one of my friend said, that before I use pointer to string, I must allocate a memory. But I looked some example C source codes, there is nothing about this. They just assign a value directly without allocating memory.

I confuse with this, because I need to read a text file to a buffer of string. So I plan to use array of pointer to string :

    char *buffer[500];
    int i = 0;

    fr = fopen("/tmp/text.txt", "rt");
    while(fgets(buffer[i],200,fr) != NULL) {
       i++;
    }
    fclose(fr);

Is this save code? or is there any better way?

Please enlightent me :)

thanks.


Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
while( buffer[i]=malloc(200)
    && fgets(buffer[i],200,fr) != NULL
){
    i++;
}

Commented:
Suppose I define pointer to string like this :

  char *str;

Then, I can assign it like this :

  str = "this is a string";

Is that assignment also allocating a memory pointed by str?

--> No, it assigns the address of that literal string to the pointer.

I meant, what happen if after that I reassign str with shorter string?

  str = "this";

Reallocated?

--> Not really.  Both litetal strings are in memory, the pointer now points to the second.  However, literal strings can be put in read-only memory.  In order to have a string on the stack, you can write char str[] = "something"; and if you want to allocate it on the heap, you first allocate memory using malloc() and then assign using strcpy() (or you can use strdup() ).

Should I care with allocation of memory?

Because one of my friend said, that before I use pointer to string, I must allocate a memory. But I looked some example C source codes, there is nothing about this. They just assign a value directly without allocating memory.

--> The memory for the strins in your examples was already allocated.  However, what happens if you want to input a string from the user?  In that case, you must allocate the memory explicitly.

I confuse with this, because I need to read a text file to a buffer of string. So I plan to use array of pointer to string :

   char *buffer[500];
   int i = 0;

   fr = fopen("/tmp/text.txt", "rt");
   while(fgets(buffer[i],200,fr) != NULL) {
      i++;
   }
   fclose(fr);

Is this save code? or is there any better way?

--> No, it is not safe, on several accounts:
1) fgets() reads from the file into the memory the pointer buffer[i] points to.  HOwever, it does not point to allocated memory.
If you know that no line will be longer than 199 characters (as your code implies), you could declare your array as buffer[200][500];
2) You have allocated 500 pointers, yet the loop can read more, if the file is longer.  Add "&& i < 500" to your "while".

Author

Commented:
Ok, I got the picture now. I rewrote my code like this :

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

int main() {
   char *s[1000];
   int  i = 0;
   char line[1000];
   FILE *fr;

   for(i=0; i<100; i++) { s[i] = NULL; }

   i = 0;

   fr = fopen("/tmp/text.txt", "rt");
   while(fgets(line,1000,fr) != NULL) {
      s[i] = malloc(strlen(line));
      strcpy(s[i], line);
      i++;
   }
   fclose(fr);

   i = 0;
   while(s[i] != NULL) {
      printf("%s",s[i]); i++;
   }

   printf("total line = %d\n",i);

   // freeing memory
   i = 0;
   while(s[i] != NULL) {
      free(s[i]); i++;
   }
}

it should safe and memory efficient (at least) ??

Because if I define chat s[500][1000] it would not be wise if the text file is small.

Thanks
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
Except what happens if the file has 1001 lines?

Commented:
Still some mistakes: 1000 vs 100.
Use #define for that.
Commented:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINES 1000
#define MAX_LINE_LEN 1000

int main()
{
    char *s[MAX_LINES] = { 0 }; // zero the pointers
    int i; // counter, no need to init
    int num_lines; // will be used later, for efficiency
    char line[MAX_LINE_LEN];
    FILE *fr;
   
    fr = fopen("/tmp/text.txt", "rt");

    for (i = 0;
         i < MAX_LINES && fgets(line, MAX_LINE_LEN, fr) != NULL;
         i++)
    {
        s[i] = malloc(strlen(line) + 1); // remember the terminating zero!
        strcpy(s[i], line);
    }

    num_lines = i; // save the actual number of lines
    fclose(fr);
   
    for (i = 0; i < num_lines; i++)
    {
        printf("%s",s[i]);
    }
   
    printf("total line = %d\n",num_lines);
   
    // freeing memory
    for (i = 0; i < num_lines; i++)
    {
        free(s[i]);
    }
}

Author

Commented:
Thanks! Great help from you :)

Commented:
Enjoy!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial