0

I am new to c and learning pointers at the moment what I know is that pointer points to the memory address of whatever it points to.

my question is this how you allocates memory exactly the length of the character or it will take 50 bytes?

Lets say they entered a title: hunger games

BOOL AddNewDVD(Database* data){

}
game on
  • 347
  • 1
  • 7
  • 22
  • `malloc(50 * sizeof(char));` already allocates a block of exactly 50 bytes. I don't see what the problem is. –  Jan 10 '14 at 20:14
  • what i want is that I want it exactly the same as the title lets say title is hunger i want to be 6 bytes instead of 50 or it could be longer than hunger – game on Jan 10 '14 at 20:15
  • 1
    @gameon: You're already doing that with the `malloc(len + 1)`. The 50 bytes is just the buffer for user input, til you stick it in that array that the second `malloc` creates. (Though i'd suggest making `title` an array within the function, rather than a pointer; then you don't have to `free` it. Right now, since you don't ever say `free(title);`, you're leaking 50+ bytes every time this function is called.) – cHao Jan 10 '14 at 20:17
  • 1
    @gameon Then `strdup()` (or `strlen()` and `malloc()`, if you want to do it manually.) –  Jan 10 '14 at 20:17
  • It is possible to reduce the allocated area by `realloc`. e.g `title = realloc(title, len + 1); data->DVDs[data->currentNumber]->name.string = title;` – BLUEPIXY Jan 10 '14 at 20:19
  • maybe he should use scanf with modifier "a" – qwr Jan 10 '14 at 20:21
  • also `" %[^\n]s"` to `" %[^\n]"` – BLUEPIXY Jan 10 '14 at 20:23
  • Eh. Personally, i'd recommend `fgets` for this. `scanf` annoys me when multi-word strings get involved. `fgets` will just get a whole line, plus it's trivial to set a maximum. – cHao Jan 10 '14 at 20:23
  • @BLUEPIXY I cant use realloc for this. I need to use only malloc. thats it – game on Jan 10 '14 at 20:23
  • why cannot use realloc ? – BLUEPIXY Jan 10 '14 at 20:24
  • @cHao I cant use any function from the String class except strlen – game on Jan 10 '14 at 20:24
  • @qwr I already modified my function for memory leak also I added free(title); at the end – game on Jan 10 '14 at 20:25
  • @gameon: This is C. There is no "String class". And `fgets` is part of stdio. – cHao Jan 10 '14 at 20:25
  • @cHao oh sorry. in this case how areyou gonna use the fgets for exact character len allocation – game on Jan 10 '14 at 20:27
  • @gameon: Trivially? You don't. You get the input into a "big enough" buffer, then copy it into a smaller array once you have all the input (and thus know the size). Just like you're already doing. :P You could devise some function that calls `fgets` or `getc` multiple times, if you wanted, but any useful solution that does that will probably require using `realloc`.) – cHao Jan 10 '14 at 20:28
  • There is no problem in your procedure . – BLUEPIXY Jan 10 '14 at 20:29
  • scanf("%ms") or scanf("%as") as I commented. they should allocate it dinamically. but only in gcc.glibs – qwr Jan 10 '14 at 20:32

3 Answers3

3

I am new to c and learning pointers

Pointers are tough for beginners. Make sure you get a solid foundation.

at the moment what I know is that pointer points to the memory address of whatever it points to.

Though that is in practice correct, that's not how I like to think of it. What you are describing is how pointers are typically implemented, not what they are conceptually. By confusing the implementation with the concept you set yourself up for writing bad code later that makes unwarranted assumptions. There is no requirement that a pointer be a number which is an address in a virtual memory system.

A better way to think of a pointer is not as an address, but rather:

  • A pointer to t is a value.
  • Applying the * operator to a pointer to t gives you a variable of type t.
  • Applying the & operator to a variable of type t gives you a pointer to t.
  • A variable of type t can fetch or store a value of type t.
  • An array is a set of variables each identified by an index.
  • If a pointer references the variable associated with index i in an array then p + x gives you a pointer that references the variable associated with index i + x.
  • Applying the [i] operator to a pointer is a shorthand for *(p+i).

That is, rather than thinking of a pointer as a number that refers to a location in memory, just think of it as something that you can force to give you a variable.

is this how you allocates memory exactly the length of the scanned string or it will take 50 bytes?

 char *title = malloc(50 * sizeof(char));
 scanf(" %[^\n]s", title);

malloc(50*sizeof(char)) gives you an array of 50 chars.

title is a pointer to char.

When dereferenced, title will give you the variable associated with the first item in the array. (Item zero; remember, the index is the distance from the first item, and the first item has zero distance from the first item.)

scanf fills in the characters typed by the user into your array of 50 chars.

If they type in more than 49 chars (remembering that there will be a zero char placed at the end by convention) then arbitrarily bad things can happen.

As you correctly note, either you are wasting a lot of space or you are possibly overflowing the buffer. The solution is: don't use scanf for any production code. It is far too dangerous. Instead use fgets. See this question for more details:

How to use sscanf correctly and safely

Community
  • 1
  • 1
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • think of a pointer is not as an address. especially, when you are going to jump from c to c++ – qwr Jan 10 '14 at 21:03
  • Note that an array of 50 characters is only enough to hold a 49 character null-terminated string. – Brian Jan 10 '14 at 22:31
0

You need to have a buffer to know how long the entered name is. This is your title, which can be filled maximum with 49 chars. Then you compute len and see it is only 6 byte long. You allocate string to have exactely this size + 1.

Of course you can then write the content of title to string, even if title is a 50 byte long buffer, and string only 7 byte long - copying of the content ends with the \0 termination char, and this is guaranteed to be inside capacity of string.

mb84
  • 683
  • 1
  • 4
  • 13
  • what will happen if I inputed more than 50 chars – game on Jan 10 '14 at 20:28
  • @gameon: overflow. mostly program crash or undefined behaviour. just make the buffer higher (e.g. 1000 byte are just 1 kb) or use dynamic growing structures. – mb84 Jan 10 '14 at 20:32
  • Note that "undefined behavior" includes running random programs on your machine. I am not merely being facetious; an expert who discovers such a bug in your software may use it to execute arbitrary code. This is called a buffer overflow exploit. Of course, this arbitrary code will be running with the same permissions as your application, so the relative concern depends on what your program is doing, where the input is coming from, and what permissions it is running with. – Brian Jan 10 '14 at 22:30
0

You cannot use scanf to determine the length of a string and then allocate memory for it. You need to either:

  1. Ask the user the length of the string. Obviously, this is a poor choice.
  2. Create a static buffer that is more than large enough and then create a dynamic string that is the exact length you need. The problem is, determining what the maximum length the string may be. fgets might be what you need. Consider the following code fragment:

    #define MAX_STR_LEN (50)
    
    char buf[MAX_STR_LEN] = {0};
    char *str, *cPtr;
    
    /* Get User Input */
    printf("Enter a string, no longer than %d characters: ", MAX_STR_LEN);
    fgets(buf, MAX_STR_LEN, stdin);
    
    /* Remove Newline Character If Present */
    cPtr = strstr(buf, "\n");
    if(cPtr)
        *cPtr = '\0';
    
    /* Allocate Memory For Exact Length Of String */
    str = malloc(strlen(buf) + 1);
    strncpy(str, buf, strlen(buf));
    
    /* Display Result */
    printf("Your string is \"%s\"\n", str);
    
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46