0

The following program runs well

#include<stdio.h>
#include <string.h>
int main() {
 char output[2][3];

 strcpy(output[0],"hello");
 
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);

}

OUTPUT

output[0] = hello
output[1] = lo

It can be observed that if string size is more data overlaps next element

if I modify the above program as given below, it shows warning and error

#include<stdio.h>
#include <string.h>
int main() {
 char output[2][3];

 strcpy(output[0],"hello world");
 
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);

}

OUTPUT **

writing 12 bytes into a region of size 6 overflows the destination

**

but if I use char pointer array, it works for any length of the string as below

#include<stdio.h>
#include <string.h>
int main() {
 char *output[2] ;

output[0]="Hello World" ;
output[1]="Country" ;
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);
 
 printf("address of output[0] = %p\n",&output[0]);
 printf("address of output[1] = %p\n",&output[1]);


}

OUTPUT

output[0] = Hello World
output[1] = Country
address of output[0] = 0x7ffe89dc4210
address of output[1] = 0x7ffe89dc4218

As can be observed size of output0 is 8, I have tried with char pointer array of size 10 also, irrespective of the number of character entered to each element of the array, the difference between the address of elements remains 8 It's also not overlapping the next element of the array also as observed in the first case.

  • How is this happening?
  • Where is memory coming from, for long strings in case of char pointer array?
  • Which is better to use char output[][] or char *output[]?

Adding one more example

#include<stdio.h>
#include <string.h>
int main() {
 char *output[2] ;

output[0]="Hello World" ;
output[1]="Country" ;
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);
 
 printf("address of output[0] = %p\n",&output[0]);
 printf("address of output[1] = %p\n",&output[1]);

output[0]="Text Parsing in c" ;
output[1]="text" ;
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);
 
 printf("address of output[0] = %p\n",&output[0]);
 printf("address of output[1] = %p\n",&output[1]);

}

OUTPUT

output[0] = Hello World
output[1] = Country
address of output[0] = 0x7fff5cf668e0
address of output[1] = 0x7fff5cf668e8
output[0] = Text Parsing in c
output[1] = text
address of output[0] = 0x7fff5cf668e0
address of output[1] = 0x7fff5cf668e8
G.ONE
  • 507
  • 1
  • 5
  • 14
  • 3
    Learning C by trial and error is guaranteed to fail. You are causing undefined behaviour. When you do so your program is no longer C. There is (almost) never any use of examining the output of a program that has undefined behaviour. – Swordfish Sep 03 '20 at 17:56
  • In the second example you do not use `strcpy` so it is hardly comparable to the first case – M.M Sep 04 '20 at 05:31
  • [Difference between pointer to pointer and pointer to array?](https://stackoverflow.com/q/6474104/3422102) – David C. Rankin Sep 04 '20 at 06:12

1 Answers1

3

You declared an array of two pointers.

char *output[2] ;

sizeof( char * ) in your system is equal to 8.

The pointers were assigned with addresses of first characters of string literals that have the static storage duration.

output[0]="Hello World" ;
output[1]="Country" ;

The string literals themselves were not copied.

You can imagine this code snippet the following way

char string_literal1[] = "Hello World";
char string_literal2[] = "Country";

char *output[2] ;

output[0] = string_literal1;
output[1] = string_literal2;

The last two assignments are equivalent to

output[0] = &string_literal1[0];
output[1] = &string_literal2[0];

As for your question

which is better to use char output[][] or char *output[] ?

then bear in mind that you may not change string literals. Any attempt to change a string literal results in undefined behavior.

So if you have for example

char *s = "hello";

then you may not write

s[0] = 'H';

But if you will declare a character array initialized by a string literal like

char s[] = "hello";

then you may write

s[0] = 'H';
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • @G.ONE You are wrong. In the declaration . char * s[2] = "hello"; there is used an invalid initializer. You may not initialize an array without using braces. – Vlad from Moscow Sep 04 '20 at 07:11
  • my mistake char *s[2]; s[0]="hello" ; s[0]="H" works and please see added fourth case in question – G.ONE Sep 04 '20 at 08:05
  • @G.ONE As I already pointed out this is undefined behavior. And your one more example added nothing new to what was said. – Vlad from Moscow Sep 04 '20 at 08:10
  • How to store 10 strings of different length in an array , (is 2d array the correct solution )? – G.ONE Sep 04 '20 at 08:50
  • @G.ONE Any way is correct. All depends on the solved task. You can declare an array of pointers or a two-dimensional array. – Vlad from Moscow Sep 04 '20 at 08:58