1

I am trying to append a character to a string... that works fine unfortunately I can't free the mem of the string afterwards which causes that the string gets longer and longer.... as it reads a file every linie will be added to the string which obviously shouldn't happen

char* append_char(char* string, char character)
{
        int length = strlen(string);
        string[length] = character;
        string[length+1] = '\0';
        return string;
}

I allocated mem for string like

char *read_string = (char *)malloc(sizeof(char)*500);

call the function append_char(read_string,buffer[0]); and free it after the whole string is build free(read_string);

I presume that once I call the append_char() , the mem allocation is going to be changed, which cause that I can't get hold of it.

Edited: here is the function which uses the append_char()

char *read_log_file_row(char *result,int t)
{
filepath ="//home/,,,,,/mmm.txt";
int max = sizeof(char)*2;
char buffer[max];
char *return_fgets;

char *read_string = malloc(sizeof(char)*500);

file_pointer = fopen(filepath,"r");

if(file_pointer == NULL)
{
    printf("Didn't work....");
    return NULL;
}   

int i = 0;

while(i<=t)
{
  while(return_fgets = (fgets(buffer, max, file_pointer)))
  {
    if(buffer[0] == '\n') 
    {
       ++i;
       break;   
    }   

        if(i==t)
    {
      append_char(read_string,buffer[0]);
     }      
   }

   if(return_fgets == NULL)
   {
      free(read_string);
      return NULL;                              
/*              return "\0";*/
        }
       if(buffer[0] != '\n') 
        append_char(read_string,buffer[0]);

   }    
   fclose(file_pointer);
    strcpy(result,read_string); 
    free(read_string);
   return result;
}
Fendrix
  • 556
  • 2
  • 11
  • 34
  • I want to free read_string,but can't – Fendrix Sep 17 '12 at 09:43
  • what do you mean by "can't free read_string"? Does the program crash during the free? or do you think you have a memory leak? Or do you mean you can still use the pointer after the free? – Tom Tanner Sep 17 '12 at 09:46
  • I still can read the string after freeing – Fendrix Sep 17 '12 at 09:47
  • 2
    @Fendrix reading the string or even attempting to do so after having called `free` is Undefined Behavior. If you do it and you still see the string, you may have just been lucky. Next time you do it, your machine may reboot or demons come out of it. Just don't do it. – Tony The Lion Sep 17 '12 at 09:50

3 Answers3

3
  1. Dont cast the return value of malloc() in C.
  2. Make sure you initialize read_string to an empty string before you try to append to it, by setting read_string[0] = '\0';.
  3. Make sure you track the current length, so you don't try to build a string that won't fit in the buffer. 500 chars allocated means max string length is 499 characters.

Not sure what you expect should happen when you do free(read_string). It sounds (from your comment to @Steve Jessop's answer) that you do something like this:

char *read_string = malloc(500);
read_string[0] = '\0';  /* Let's assume you do this. */
append_char(read_string, 'a'); /* Or whatever, many of these. */
free(read_string);
print("%c\n", *read_string); /* This invokes UNDEFINED BEHAVIOR. */

This might print an a, but that proves nothing since by doing this (accessing memory that has been free():d) your program is invoking undefined behavior, which means that anything could happen. You cannot draw conclusions from this, since the "test" is not valid. You can't free memory and then access it. If you do it, and get some "reasonable"/"correct" result, you still cannot say that the free():ing "didn't work".

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • thanks read_string[0] = '\0'; solved the problem... but as I more familiar with Java I am really curious why this happens especially I call the read_log_file_row function within a loop, and still it append a new line to read_string even freeing it.... as undef. behaviour should be as it says undefined this reaction is defined as it doesn't free the heap even after 30 times it reacts same... just for the next time.. how do I know as C beginner that it is a undefined behaviour ? – Fendrix Sep 17 '12 at 10:20
  • "how do I know as C beginner that it is a undefined behaviour" - you read a book or tutorial about C, and you only do the things it tells you that you can do. You don't do things that your experience in other languages suggests to you *might* be OK in C, until you've checked that they are. – Steve Jessop Sep 17 '12 at 10:32
  • To put it another way -- programming C is like walking in a minefield. Your past experience of walking in other kinds of field isn't as much use here as you might hope, you're going to have to learn a new way of proceeding :-) Every language has things that you can do that will cause confusing or intermittent bugs, but C probably has more than most. – Steve Jessop Sep 17 '12 at 11:26
1

No, the memory allocation is not changed in any way by append_char. All it does is change the contents of the allocation -- by moving the nul terminator one byte along, you now care about the contents of one more of your 500 bytes than you did before.

If the string gets longer than 500 bytes (including terminator), then you have undefined behavior. If you call strlen on something that isn't a nul-terminated string, for example if you pass it a pointer to uninitialized memory straight from malloc, then you have undefined behavior.

Undefined behavior is bad[*]: feel free to read up on it, but "X has undefined behavior" is in effect a way of saying "you must not do X".

[*] To be precise: it's not guaranteed not to be bad...

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • so why is free(read_string); not deleting the string... I can still read the content of the string after freeing – Fendrix Sep 17 '12 at 09:44
  • @Fendrix where is it specified `free` would delete the content of the string? What is specified is you should not read the string after it has been freed, – ouah Sep 17 '12 at 09:47
  • 1
    @Fendrix: just because you can read the contents doesn't mean it hasn't been freed. Accessing the memory after you freed it has undefined behavior. The result of this undefined behavior can be anything, including that you still see the previous contents of the memory. See http://stackoverflow.com/a/6445794/13005. It was written about C++ (and automatic variables), but the analogy applies equally to C (and dynamic allocations). – Steve Jessop Sep 17 '12 at 09:47
  • 1
    @Fendrix, freeing the string does not modify the memory or the pointer to the memory, so you can still access it. It is however undefined behaviour and no guarantees on the contents or access can be given. – r_ahlskog Sep 17 '12 at 09:49
0

Have you ever initialized the string? Try *read_string=0 after allocating it. Or use calloc. Also, have your string grown beyond the allocated memory?

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173