Search code examples
cfunctionmallocstrlen

Do I add +1 to memory allocation in function after removing newline character in main?


If I prompt user to give filename as input, then check for and remove newline character do I still have to add +1 to strlen(filename) when allocating memory i function, because of using strlen and the fact that it counts characters without the last character?

Or there's no need for that since I removed it in main()?

I've read that not adding +1 can allocate to little memory for string and cause problems, but I read contradictory things on the matter and would appreciate some clarification.

double** wczytaj_macierz (char* filename, int x, int y)
{
  char    *file = malloc(strlen(filename) + 1);

  sprintf(file, "%s", filename);
  FILE *fin = fopen (file, "r");



...
rest of the code
...

int main(void)
   char    filename[BUFSIZ];
{
  printf("\nPlease enter filename, max %d characters.\n", sizeof(filename));
  if (fgets(filename, sizeof(filename), stdin) != NULL)
  {
    if ((p = strchr(filename, '\n')) != NULL) 
    {
      *p = '\0';
    }
  }
wczytaj_macierz (filename, x, y);

Solution

  • When you allocate memory for a string, you must always allocate one more byte than the length of the string. That extra byte is for the terminating '\0' character.

    If you have a string that happens to end in a newline \n character, and you strip that character off, you will obviously make the string one character shorter, and this means you will need one less byte of memory to store it. But storing it will still require space for the \0, as always.

    As an example:

    char string[] = "test\n";
    int stringlen = strlen(string);            // length = 5
    char *copy1 = malloc(stringlen + 1);       // allocates 6 bytes
    strcpy(copy1, string);                     // this works
    char *p = strchr(string, '\n');            // find the \n
    if(p != NULL) *p = '\0';                   // strip it off
    printf("string is now: \"%s\"\n", string);
    stringlen = strlen(string);                // length = 4
    char *copy2 = malloc(stringlen + 1);       // allocates 5 bytes
    strcpy(copy2, string);                     // this works also
    

    Now, if you wrote the code like this:

    char string[] = "test\n";
    int stringlen = strlen(string);
    char *p = strchr(string, '\n');
    if(p != NULL) *p = '\0';
    printf("string is now: \"%s\"\n", string);
    char *copy = malloc(stringlen);           // don't have to add 1,
                                              // since I just stripped off \n
    strcpy(copy, string);
    

    it looks like you can get away with not adding the + 1. But any time you have to add a comment to explain some code that's not there, and especially if the comment you have to write is longer than the code it replaces, it's usually a sign that you've gotten too clever, that you ought to just leave the code in. And, indeed, even though it might seem to work at first, writing the code this way would be pretty dangerous, because if you ever end up with a string that doesn't end in \n, meaning that there's nothing to strip off, the code will stop working properly.