Home > Software engineering >  Allocating and freeing memory in C
Allocating and freeing memory in C

Time:08-10

I'm trying to paste two strings together. I know you can do it faster but I'm not allowed to use build-in functions. I allocate memory for string3 and in main the memory should be released but it is not. I'm not allowed to change anything in main. What am I doing wrong?

Allocating memory happens here:

 char *string_cat( char const *string1, char const *string2 )
{
    int lengte1 = string_length(string1);
    int lengte2 = string_length(string2);
    int totaal_lengte = lengte1 lengte2;
    char *string3 = (char*) malloc(totaal_lengte*sizeof(char));
    int i = 0;
    int j = 0;
    while(string1[i] != '\0'){
        string3[j] = string1[i];
        i  ;
        j  ;
    }
    i = 0;
    while(string2[i] != '\0'){
        string3[j] = string2[i];
        i  ;
        j  ;
    }
    return string3;
}

Freeing memory happens here:

 int main( int argc, char **argv )
    {
        char *str;
        
        printf( "== string_cat ==\n" );
        check( strcmp( ( str = string_cat( "", ""       ) ) == NULL ? "" : str, ""      ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "", "abcdef" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "a", "bcdef" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "ab", "cdef" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "abc", "def" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "abcd", "ef" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "abcde", "f" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        check( strcmp( ( str = string_cat( "abcdef", "" ) ) == NULL ? "" : str, "abcdef" ) == 0, __FILE__, __LINE__ ); free( str );
        return 0;
    }

CodePudding user response:

  1. Do not cast the result of malloc. It you are getting the error it means that you compile C code using C compiler which is not right.
  2. You need extra space for null terminating character.
  3. sizeof(char) is by definition 1, but if you want to check it (for example strings can be multibyte chars - use objects not types in sizeof
  4. Use the correct type for size (ie size_t)
  5. You can modify while loops to include null terminating character in the last copy
  6. Chech the result of malloc
  7. It is good to check if parameters are OK
size_t string_length(const char *s)
{
    const char *end = s;
    while(*end) end  ;
    return end - s;
}

char *string_cat( char const *string1, char const *string2 )
{
    char *string3 = NULL;
    if(string1 && string2)
    {
        size_t lengte1 = string_length(string1);
        size_t lengte2 = string_length(string2);
        size_t totaal_lengte = lengte1 lengte2;
        char *tmp;
        string3 = malloc((totaal_lengte   1) * sizeof(*string3));

        if(string3)
        {
            tmp = string3;
            while(*string1) *tmp   = *string1  ;
            while((*tmp   = *string2  ));
        }
    }
    return string3;
}

CodePudding user response:

  • You need to allocate the memory 1, with malloc you maybe need to set the last value to '\0' with calloc it will initialize the memory
    to zero.
  • You can override the default functions with your own, not a big thing but helps with reading the code.
  • Its better to compare constants first to the variable like '\0' == val, this will prevent mistakes like val = '\0'.
  • Put free on a new line, this is for readability and makes things less confusing.
  • This is more of personal opinion, but I don't see the need for space between brackets as it just increases the file size with no benefit, instead I would use new lines more.
  • Its stated and is a minor thing but casting from void to char is not a C thing.
#include<stdlib.h>
#include<string.h>
#include<stdio.h>

size_t strlen(char const* str) {
   size_t i;
   for (i = 0; '\0' != str[i]; i  );
   return i;
}

void* memcpy(void* restrict dst, const void* restrict src, size_t bytes) {
   char* d = dst;
   const char* s = src;

   for (int i = 0; i < bytes; i  ) {
      d[i] = s[i];
   }

   return d;
}

char* string_cat(char const* str1, char const* str2) {
   int len1 = strlen(str1);
   int len2 = strlen(str2);
   
   /// calloc will set memory block to zero
   char* out = calloc(1, len1   len2   1);

   memcpy(out, str1, len1);
   memcpy(&out[len1], str2, len2);

   return out;
}

int check(int state, const char* file, int line) {
   if (!state) {
      printf("File %s on line %d is not the same\n", file, line);
   }
   return 0;
}

int main(int argc, char **argv) {
        char *str;
        
        printf("== string_cat ==\n");
    check(strcmp((str = string_cat("", "")) == NULL
         ? "" : str, "") == 0, __FILE__, __LINE__);
    free(str);
        
    check(strcmp((str = string_cat("", "abcdef")) == NULL
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__); 
    free(str);

        check(strcmp((str = string_cat("a", "bcdef")) == NULL 
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__); 
    free(str);
        
    check(strcmp((str = string_cat("ab", "cdef")) == NULL 
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__);
    free(str);
        
    check(strcmp((str = string_cat("abc", "def")) == NULL 
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__); 
    free(str);

        check(strcmp((str = string_cat("abcd", "ef")) == NULL
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__); 
    free(str);
        
    check(strcmp((str = string_cat("abcde", "f")) == NULL 
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__);
    free(str);
        
    check(strcmp((str = string_cat("abcdef", "")) == NULL
         ? "" : str, "abcdef") == 0, __FILE__, __LINE__);
    free(str);
        return 0;
}
  • Related