-1

We can store string using 2 methods.

Method 1: using array

char a[]="str";

Method 2:

char *b="str";

In method 1 the memory is used only in storing the string "str" so the memory used is 4 bytes.

In method 2 the memory is used in storing the string "str" on 'Read-Only-Memory' and then in storing the pointer to the 1st character of the string. So the memory used must be 4 bytes for storing string in ROM and then 8 bytes for storing pointer (in 64-bit machine) to the first character.

In total the 1st method uses 4 bytes and the method 2 uses 12 bytes. So is the method 1 always better than method 2 for storing strings in C/C++.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
user1825567
  • 153
  • 1
  • 9
  • In method one, `a` is still a pointer to the data "str", just with some syntactic sugar. – Colin Jan 19 '17 at 10:11
  • And why do you think `a` does not occupy any memory in Method 1? What is `a` in your opinion? – PeterK Jan 19 '17 at 10:11
  • there is no *"ROM"* inside of your computer ... – specializt Jan 19 '17 at 10:12
  • @specializt I suspect there is some ROM inside most computers. – Colin Jan 19 '17 at 10:13
  • Yes, inside of chips on the motherboard - all of which are inaccessible to mortal beings. In terms of programming : no, absolutely not, everything is RAM / writable memory – specializt Jan 19 '17 at 10:14
  • @specializt: Everything is writable? Definitely not. In many embedded systems there is some flash memory where all the code and static data is located and where the these data will reside also during execution. – Gerhardh Jan 19 '17 at 10:18
  • @PeterK a is an array. And it occupies a size of 4 bytes which is why i pointed that method 1 occupies 4 bytes of space. The statement sizeof(a) will give 4 – user1825567 Jan 19 '17 at 10:19
  • @Gerhardh nobody is talking about embedded systems, microcontrollers, assembler and the likes. This question is about C and strings, he wont be able to access any ROM without using buffer overflows and whatnot.Also : you should lookup the term "flash memory" - its **writable by design** – specializt Jan 19 '17 at 10:22
  • `sizeof(a)` will give you the size of the array, true, but that is not how much memory `a` itself occupies. As @Colin__s said it is still a pointer, so it itself occupies 8 bytes (on 64bit systems). – PeterK Jan 19 '17 at 10:24
  • @user1825567 `sizeof` isn't doing what you apparently think it is, and if you pick **a** language I'll answer to explain why. – WhozCraig Jan 19 '17 at 10:24
  • 2
    I don't understand the downvotes on this question, it's clear and valid. – Colin Jan 19 '17 at 10:26
  • 1
    @Colin__s personally i downvoted because the OP is asking a question but then rejecting explanations and insisting on what he thinks is the answer. At least thats my impression from his reactions. – PeterK Jan 19 '17 at 10:28
  • @PeterK when did i reject the answers? I have just given my opinion as you asked me about it. – user1825567 Jan 19 '17 at 10:32
  • An array identifier is a hidden pointer and will often be treated as such internally.A system might micro-optimise the examples differently, but probably won't. – Malcolm McLean Jan 19 '17 at 11:31

3 Answers3

2

Except if you use a highly resource limited system, you should not care too much for the memory used by a pointer. Anyway, optimizing compilers could lead to same code in both cases.

You should care more about Undefined Behaviour in second case!

char a[] = "str";

correctly declares a non const character array which is initialized to "str". That means that a[0] = 'S'; is perfectly allowed and will change a to "Str".

But with

char *b = "str";

you declare a non const pointer to a litteral char array which is implicitely const. That means that b[0] = 'S'; tries to modify a litteral string and is Undefined Behaviour => it can work, segfault or anything in between including not changing the string.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

All of the numbers that you cite, and the type of the memory where the string literal is stored are platform specific.

Which is more efficient way for storing strings, an array or a pointer

Some pedantry about terminology: A pointer can not store a string; it stores an address. The string is always stored in an array, and a pointer can point to it. String literals in particular are stored in an array of static storage duration.

Method 1: using array char a[]="str";

This makes a copy of the content of the string literal, into a local array of automatic storage duration.

Method 2: char *b="str";

You may not bind a non const pointer to a string literal in standard C++. This is ill-formed in that language (since C++11; prior to that the conversion was merely deprecated). Even in C (and extensions of C++) where this conversion is allowed, this is quite dangerous, since you might accidentally pass the pointer to a function that might try to modify the pointed string. Const correctness replaces accidental UB with a compile time error.

Ignoring that, this doesn't make a copy of the literal, but points to it instead.

So is the method 1 always better than method 2 for storing strings in C/C++.

Memory use is not the only metric that matters. Method 1 requires copying of the string from the literal into the automatic array. Not making copies is usually faster than making copies. This becomes more and more important with increasingly longer strings.

The major difference between method 1 and 2, are that you may modify the local array of method 1 but you may not modify string literals. If you need a modifiable buffer, then method 2 doesn't give you that - regardless of its efficiency.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Additional considerations:

Suppose your system is not a RAM-based PC computer but rather a computer with true non-volatile memory (NVM), such as a microcontroller. The string literal "str" would then in both cases get stored in NVM.

In the array case, the string literal has to be copied down from NVM in run-time, whereas in the pointer case you don't have to make a copy, you can just point straight at the string literal.

This also means that on such systems, assuming 32 bit, the array version will occupy 4 bytes of RAM for the array, while the pointer version will occupy 4 bytes of RAM for the pointer. Both cases will have to occupy 4 bytes of NVM for the string literal.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • And if my system is a laptop which is 64bit machine, then array version will occupy 4byte of RAM and pointer will occupy 8 byte of RAM and both these will occupy 4byte of NVM. Did i get it right? – user1825567 Jan 19 '17 at 14:27
  • @user1825567 Probably, though C does not guarantee that `int` is 4 bytes nor that a pointer is 8 bytes. Also note than on such a computer with lets say 8GB RAM, your 8 byte pointer occupies approximately 0.000000000097% of the total RAM. Meaning that the storage space occupied by this pointer is probably the least important thing you ever need to worry about. – Lundin Jan 19 '17 at 14:51
  • i get your point. But i am not looking for practical answers, just the theoretical answer whether or not this thing is true on paper. So whats your take if i am really concerned about the my resource? – user1825567 Jan 19 '17 at 14:57
  • @user1825567 Functionality-wise, the two versions have different meaning and uses. The first one gives you a read/write string and the second a read-only string constant. So you are kind of comparing apples and oranges to begin with. – Lundin Jan 19 '17 at 15:21
  • So if my objective is to store string or take string as input then which will be better in terms of memory efficiency? – user1825567 Jan 20 '17 at 02:31