3

I am refreshing my C skills. I am using a char *s and using malloc to allocate memory to the s. Then using scanf, I read the input to s. But my question is I haven't specified a size for the memory chunk. But the program works. How does the memory gets allocated for the arbitrary length of the input string? Is scanf simply incrementing the pointer and writing data into the location?

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

int main() {
    char *s;
    s = (char *) malloc(sizeof(s));    //I did not specify how much like malloc(sizeof(s) * 128)
    if (s == NULL) {
        fprintf(stderr, "\nError allocating memory for string");
        exit(1);
    }
    scanf("%s", s);
    puts(s);
    free(s);
    return 0;
}

/*
    Input:
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    Output:
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*/

6 Answers6

4

With char *s;, sizeof(s) is the same as sizeof(char *) which is either 4 or 8 depending on whether you are on a 32 bit box or a 64 bit box.

IF you are on a 32 bit box then you can store 3 characters plus the null 'end of string' character. IF you store more it may explode.

  • But it is not exploding. See the input and output. –  Oct 23 '12 at 04:27
  • 4
    @kadaj: It's undefined behaviour. Maybe it works, maybe tomorrow it doesn't work, maybe you put it on a friend's computer and it lights the CPU on fire. You cannot, and should not, rely on this working. – nneonneo Oct 23 '12 at 04:36
1

sizeof(s) returns the size in bytes of s which is of type char*. Typically on a 32 but machine this is 4 bytes and 8 byts on a 64 bit machine. So you actually have told malloc the number of bytes to allocate and s will point to that region of memory.

sashang
  • 11,704
  • 6
  • 44
  • 58
1

You did specify a size: sizeof(s). Since s is a char *, sizeof(s) == sizeof(char *). Depending on your platform, this may be 4 or 8 bytes in length.

So, you've effectively allocated 4 (or 8) bytes to store a string. If you type more than 3 (or 7) characters on the command line, then you are going to start writing past the end of the allocated array, which triggers undefined behaviour. With undefined behaviour, anything could happen: your program might look like it works fine, the program might fill the rest of the memory with ZALGO, the program might segfault horribly, or you might encounter the ever-popular nasal demons. The C specification does not specify what happens (hence the term "undefined behaviour").

The fact that your program "works" at all is a complete fluke, and should never be relied upon.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
1

sizeof(s) is you case returns the size of a character pointer, which will be 4 or 8 bytes depending on if you are running on a 32 or 64 bit platform.

You want to use sizeof(*s) instead. However, since the C standard specifies that sizeof(char) (which is what sizeof(*s) will be) is one, so for character arrays you don't need it.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

it will only allocate the space =size of char * and than simply incrementing the pointer and writing data into the location? as you thought.

the answer for why it works is: because its writing it on the memory area which is not allocated to you but if the area is reserved by some other process your program will crash. so better allocate a larger space.

rbhawsar
  • 805
  • 7
  • 25
  • No modern OS is going to let you write to "some other process" 's memory space with this method. Memory is virtually addressed. You could be writing over other areas of your own process that shouldn't be. – Joe McGrath Feb 03 '17 at 00:51
0

You are only allocating memory of size equal to size of Integer. If you write strings of greater length to this variable, it will just overwrite the existing memory locations and well, your program will show unexpected behavior.

Vikram Singh
  • 1,726
  • 1
  • 13
  • 25
  • 1
    1) there is no `Integer` in C, only `int`; 2) `sizeof(s) == sizeof(char *)`, which may not be equal to `sizeof(int)`. – nneonneo Oct 23 '12 at 04:27
  • sizeof(s) == sizeof(char *). Isn't pointer to a character, an address? How are addresses stored? Not as integers? May be long? – Vikram Singh Oct 23 '12 at 04:30