1

Currently learning memory management in C, and I am currently running into issues increasing string length as a loop iterates.

The method I am trying to figure out logically works like this:

// return string with "X" removed


char * notX(char * string){

   result = "";

   if(for int = 0; i < strlen(string); i++){
      if (string[i] != 'X') {
         result += string[i];
      }
   }

   return result;
}

Simple enough to do in other languages, but managing the memory in C makes it a bit challenging. Difficulties I run into is when I use malloc and realloc to initialize and change size of my string. In my code I currently tried:

char * notX(char * string){

   char* res = malloc(sizeof(char*)); // allocate memory for string of size 1;
   res = ""; // attempted to initialize the string. Fairly certain this is incorrect
   char tmp[2]; // temporary string to hold value to be concatenated

   if(for int = 0; i < strlen(string); i++){
      if (string[i] != 'X') {

         res = realloc(res, sizeof(res) + sizeof(char*)); // reallocate res and increasing its size by 1 character
         tmp[0] = string[i];
         tmp[1] = '\0';
         strcat(res, tmp);

      }
   }

   return result;
}

Note, I have found success in initializing result to be some large array like:

char res[100];

However, I would like to learn how to address this issue with out initializing an array with a fixed size since that might potentially be wasted memory space, or not enough memory.

3
  • 2
    malloc(sizeof(char*)) = allocating the size of a pointer. Further, realloc(res, sizeof(res) + sizeof(char*)); reallocates to the size of two pointers always. I don't think you understand how sizeof works. And res = ""; causes two catastrophes. (1) it leaks the memory allocated just one line prior, and (2) it now causes res to point to a constant string, i.e. memory no longer dynamically managed, therefore passing it to realloc invokes undefined behavior. Commented Dec 21, 2019 at 14:02
  • 2
    Your result string will never be larger than the original string, so you can start by allocating len +1 characters. At the end of the loop you could decide to realloc() it. Commented Dec 21, 2019 at 14:07
  • Other problems include recomputing strlen(string) every single iteration, even though it is constant. As is, you wouldn't even need to know the length since you could just iterate until you hit the NUL terminator. Likewise repeated strcat gets increasingly ineffective since it needs to find the end of the string every time. Rather keep track of the end position and append there. (Note that these are more long-term things to consider and ways of thinking in general, first learn how memory allocation, pointers and sizeof work, and the difference between arrays and pointers.) Commented Dec 21, 2019 at 14:14

2 Answers 2

1

realloc needs the number of bytes to allocate. size is incremented for each character added to res. size + 2 is used to provide for the current character being added and the terminating zero.
Check the return of realloc. NULL means a failure. Using tmp allows the return of res if realloc fails.

char * notX(char * string){

   char* res = NULL;//so realloc will work on first call
   char* tmp = NULL;//temp pointer during realloc
   size_t size = 0;
   size_t index = 0;

    while ( string[index]) {//not the terminating zero
        if ( string[index] != 'X') {
            if ( NULL == ( tmp = realloc(res, size + 2))) {//+ 2 for character and zero
                fprintf ( stderr, "realloc problem\n");
                if ( res) {//not NULL
                    res[size] = 0;//terminate
                }
                return res;
            }
            res = tmp;//assign realloc pointer back to res
            res[size] = string[index];
            ++size;
        }
        ++index;//next character
    }
    if ( res) {//not NULL
        res[size] = 0;//terminate
    }
   return res;
}
Sign up to request clarification or add additional context in comments.

Comments

0

2 main errors in this code:

  • the malloc and the realloc function with parameter that call sizeof(char*). In this case the result of sizeof(char*) is the size of a pointer, not of a char, so you have to substitute the char* with char in the sizeof function.

  • res = ""; is incorrect. You primarly have a memory leak because you lose the pointer to the just allocated memory in malloc function, secondary but not less important, you have an undefined behavior when call realloc function over res initialized as an empty string ( or better a constant string), after the above initialization the memory is no longer dinamically managed. To substitute this initialization i think a memset to 0 is the best solution.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.