0

I have to read a string from stdin, allocating memory dinamically without wasting it. I've done this, but i'm not convinced about it,because in this way i think i waste memory!

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

char *alloc_memory(int n)
{
    char *p;
    p=malloc(n*sizeof(char));
    if(p==NULL)
    {
        fprintf(stderr,"Error in malloc\n");
        exit(EXIT_FAILURE);
    }
    return p;
}


int main(int argc, char *argv[])
{
    if(argc != 1)
    {
        fprintf(stderr,"Usage: %s \n",argv[0]);
        return EXIT_FAILURE;
    }

    char string[64];
    int lung;
    char *p,*s,*w;

    printf("Insert string: \n");

    p=fgets(string,63,stdin);
    if(p==NULL)
    {
        fprintf(stderr,"Error in fgets\n");
        exit(EXIT_FAILURE);
    }

    printf("You've inserted: %s", string);

    lung=strlen(p);

    s = alloc_memory(lung+1);

    w=strncpy(s,p,lung);

    printf("Final string:%s", w);   

    return EXIT_SUCCESS;

}

any idea? Should i read one character at a time?

10
  • 4
    What memory do you think you're wasting? (Apart from the obvious leak.) Commented Sep 1, 2013 at 10:44
  • the memory allocated with char string[64] Commented Sep 1, 2013 at 10:46
  • 1
    One character at a time will be much slower (and user will get irritated :P) than your approach. You are not wasting any memory, other than the fact that your program is allocating dynamic memory continuously without ever releasing it (which is bad^infinity). Commented Sep 1, 2013 at 10:47
  • 1
    For this? Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated. Commented Sep 1, 2013 at 11:53
  • 1
    @Butterfly: Exactly that's the dangerous "feature" of strncpy(). Commented Sep 1, 2013 at 12:08

1 Answer 1

2

To have char str[64] (string is not a good name for a variable, it might lead to ambiguities) declared only temporarily just put it in a local context:

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

char * alloc_memory(size_t n)
{
  char * p = malloc(n); /* * sizeof(char) is always 1 */

  if (p == NULL)
  {
    fprintf(stderr, "Error in malloc() when trying to allocate %zu bytes.\n", n);
    exit(EXIT_FAILURE);
  }

  memset(p, 0, n); /* Avoid having strncpy() choke .. later down in this example. */

  return p;
}

int main(int argc, char * argv[])
{
  if (argc != 1)
  {
    fprintf(stderr, "Usage: %s \n", argv[0]);
    return EXIT_FAILURE;
  }

  {
    char * w = NULL;

    printf("Insert string: ");

    {
      char str[64]; /* here str is allocated */
      char * p = fgets(str, 63, stdin);
      if (p == NULL)
      {
        fprintf(stderr, "Error in fgets().\n");
        exit(EXIT_FAILURE);
      }

      printf("You've inserted: '%s'\n", str);

      {
        size_t lung = strlen(p);
        char * s = alloc_memory(lung + 1);

        w = strncpy(s, p, lung);
      }
    } /* here "str" is deallocated */

    printf("Final string: '%s'\n", w);
  }

  return EXIT_SUCCESS;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Or you can malloc() string and then free() it once the data is copied to a new buffer.
@Butterfly: Please see my comment (on the usage of strncpy()) to your question.
Btw, a local scope is sometimes a hint that it should be split into its own function. In this case, something like char* read_alloc_line(FILE* f);
In alloc_memory, why not use calloc rather than malloc and save the memset?

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.