Mukul Shukla
Mukul Shukla

Reputation: 123

C Char pointers

Let us say we have a array of pointers:

char *ptr[30];

Now this works fine, and doesn't seems to do anything unexpected! I can input names easily.

scanf("%s", ptr[1]);
scanf("%s", ptr[2]);
scanf("%s", ptr[3]);

printf("%s\n", ptr[1]);
printf("%s\n", ptr[2]);
printf("%s\n", ptr[3]);

My question is if a pointer can be used in this way to store end number of names, then why is malloc used.? and in this case ptr[1] does not point to the character in the input but to a new input itself. for eg if ptr has mukul, ptr[1] should point to 'u' and if space is not allocated when a pointer is declared like this, what are the limits.?

Upvotes: 4

Views: 3775

Answers (4)

John Bode
John Bode

Reputation: 123458

You've allocated space for 30 pointers, but you haven't initialized them to point anywhere meaningful. Unless you declared the array outside of a function, each element in the array will contain some random bit string that may or may not correspond to a writable memory location. If we drew a picture, it would look something like this (all addresses are pulled out of thin air; don't assume this corresponds to any real architecture):

Item       Address       0x00  0x01  0x02  0x03
----       -------       ----  ----  ----  ----
ptr        0xbbc81230    0x??  0x??  0x??  0x??
           0xbbc81234    0x??  0x??  0x??  0x??
           0xbbc81238    0x??  0x??  0x??  0x??
           ...
           0xbbc812a8    0x??  0x??  0x??  0x??           

where 0x?? represents a random byte value. For the behavior you've described, each of the random values just happens to point to writable memory, and writing over whatever's stored there just happens to not have any immediate ill effects.

Bad juju: it looks like your code is working properly when in reality it's behaving very badly, and can lead to some nasty runtime problems elsewhere in your program that's a pain to debug.

You will need to explicitly set each element of the ptr array to point to a valid memory location before attempting to write through it.

Suppose we add the following code:

ptr[0] = malloc(strlen("foo") + 1);
strcpy(ptr[0], "foo");
ptr[1] = malloc(strlen("bar") + 1);
strcpy(ptr[1], "bar");

We've dynamically allocated some extra memory to hold a couple of strings, and stored the pointers to those new buffers to ptr[0] and ptr[1].

Our picture would now look something like this:

Item       Address       0x00  0x01  0x02  0x03
----       -------       ----  ----  ----  ----
           0x80ff0000     'f'   'o'   'o'  0x00
           ...
           0x80ffcdc0     'b'   'a'   'r'  0x00
           ...
ptr        0xbbc81230    0x80  0xff  0x00  0x00
           0xbbc81234    0x80  0xff  0xcd  0xc0
           0xbbc81238    0x??  0x??  0x??  0x??
           ...
           0xbbc812a8    0x??  0x??  0x??  0x??           

ptr[0] now contains the address of a buffer sized to hold 4 char values, and we copy the string "foo" to that buffer. Similarly, ptr[1] contains the address of another 4-byte buffer that now contains the string "bar".

Upvotes: 3

vsz
vsz

Reputation: 4909

If you use what is in your example, you just owerwrite other locations what come after your ptr array. Most compilers should actually give at least a warning. Your program would crash on most systems, you were just very lucky.

Upvotes: 4

Gil
Gil

Reputation: 3334

When you define a pointer like:

char *ptr = 0; // NULL pointer: dereferencing it will crash
puts(ptr);    // crash

You merely create a link to a place in memory:

ptr = "string"; // dereferencing it will show the string
puts(ptr);     // displaying "string"

So having an array of pointers merely creates a list of references to other variables.

To reference a place in memory, you then have to assign variables to your pointers, or allocate memory for each pointer.

Upvotes: 3

Charles Salvia
Charles Salvia

Reputation: 53289

The pointer cannot be used that way. It might "work" for you sometimes by sheer chance, but using a pointer without allocating memory for it will cause undefined behavior - meaning that your program may behave erratically and give you unexpected results.

Remember, just because your program compiles and runs doesn't mean it is correct. In the C language there is a whole class of errors known as "undefined behavior", many of which the compiler will happily let you do without complaining. These include overwriting a buffer, using an uninitialized variable, or dereferencing a pointer that doesn't point to a legitimately allocated memory block. Programs that exhibit undefined behavior may even appear to work normally sometimes - but they are usually very unstable and prone to crash.

Upvotes: 13

Related Questions