Is there problem to declare an empty char array?

Pages: 12345
But what I wrote is appropriate? Is that how it works?
So what do people who have to save on memory do? If they had to store different string literals in one string variable?

Instead of char var[3] = "hi" can we do something like assign(var, <hi>) and hi is not a literal but an expression rather? Because expressions are rvalues right?


Why are string literals static? Why aren't they deallocated after they are obsolete? There must be a reason..
Last edited on
closed account (42TXGNh0)
@jonnin
Yup, I know that method but I don't want to over-size an array to put a value which wouldn't use up all the spaces in it. I wouldn't have asked this question if I have used that method. :(
closed account (42TXGNh0)
@Repeater
Alas, it's okay to not use static in main() but it's important to use it in a function, so that I can have the returned pointer pointing at something un-destroyed. But never mind, that's not really important to the question.

By the way, I can't edit the value of a pointer. That's giving me a headache...
1
2
3
char * c = "This";
strcat(c," is a sentence."); // and the program crashes here
printf(c);
Last edited on
closed account (42TXGNh0)
I wish to have a method that works in C which I don't need to over-size the array...
If no, that's not going to work, then I will wish for a method that can change the value of the object which the pointer is pointing to.
Like JLBorges said,

char * c = "This";

Is equivalent to

1
2
3
static char var[5] = "This";
char * c = &var[0];
// c now points to var's first index 


When you write strcat(c, " is a sentence");
You're trying to overwrite var which can only hold 5 characters with sizeof(" is a sentence.") extra characters. So you're basically writing in memory that is out of bounds.

You only use char * c = "This"; if you only want to only read through the string "This" and do nothing else.

What are you trying to do?
closed account (42TXGNh0)
Make a header that is 100% safe because I don't want to risk a crash.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdbool.h>
#include <string.h>

char * p(char * s, char c[] , int i , bool rv) {
	/* s: receives the argument(s)
	   c: acceptable header(s) of the argument
	   i: how many character(s) as the header of the argument
	   rv: return value: true for returning the header ; false for returning the argument (header removed)
	    Those so called arguments means those who came from the command-line. */
	char h[i],w[i];
	strncpy(h,s,i); h[i] = '\0';
	int l;
	static char r[] = ""; // this may lead to the realm of undefined behavior
	for (l = 0 ; l <= (int)(strlen(c) / i) ; l++) {
		strncpy(w,c+l*i,i); w[i] = '\0';
		if (strcmp(h,w) == 0) {
			if (rv) { strcpy(r,h); } else {
				char v[strlen(s) - i];
				strcpy(v,s+i);
				v[strlen(s)-i] = '\0';
				strcpy(r,v);
			};
			return r;
		};
	};
	strcpy(r,s);
	return r;
}


In this case, I would need to wish for those two wishes to come true. http://www.cplusplus.com/forum/beginner/248142/3/#msg1093953
Last edited on
Alas, it's okay to not use static in main() but it's important to use it in a function, so that I can have the returned pointer pointing at something un-destroyed


Sounds like what you actually want is "dynamic memory". In C, that's done with malloc and free.

1
2
char * c = "This";
strcat(c," is a sentence."); // and the program crashes here 

Well of course it does. You're trying to write over some memory that wasn't allocated to you. You're trying to write over the memory next to "This". Is that memory yours to write in? No. You can't just go writing over bits of memory at random.

You are making all of this so much harder than it really is. You're doing all sorts of crazy things. None of this makes any sense. Please, just learn about pointers, learn about memory, and just do it the simple, easy way.
Last edited on
Why are string literals static? Why aren't they deallocated after they are obsolete? There must be a reason..


A string literal is written into the actual executable (or library). If you open up the compiled binary file with an editor, you'll find the text of the string literal.

When a program is run, Some (or all) of it it is loaded into memory. Some (or all) of that is loaded into read-only memory; memory that has been specifically designated as off-limits for the program to write to. The string literals are in a section of the program that goes in read-only memory.

Last edited on
Does how much ROM you can have depend on storage capability of the device?

But wait.. the pointer is pointing to ROM? huh?
Last edited on
closed account (42TXGNh0)
@Repeater I'll try... I'm really not good at that. Those things seems to destruct my patience.
Anyway, how can I make a dynamic memory?
closed account (42TXGNh0)
@Grime Sorry, are you asking me or him?
@arnoldLai
It's done with malloc and free

I'm really not good at that. Those things seems to destruct my patience.

Then you have two choices:

1) Get good at it
2) Don't write C code

Which is it to be? Pick one. If you want to write C code, you need to understand memory. You need to understand pointers. If that's not something you're willing to do, don't write C code.
closed account (42TXGNh0)
Can I choose both? (XD)
I wouldn't give up on something easily so I'll choose the first one. Never a problem to learn something new, but it really dispatches my interest when no one's guiding me after I had failed for so many times.

I can't simply free() it outside the function but I can't free it before the function has returned... That's the reason for me to not using malloc() and free().

My target is making a header and I don't wish to bother the users (if I have chance to make it as an open source) from free()ing, I wanna do it in the header.
Last edited on
that is how pointers work.

you can't have your pointer and release it too. You can fix this in c++ with a class that destroys the memory when it goes out of scope. You can't fix it in C unless they have added destructors to structs in C, which I don't think has happened. I have lost track of C's updates and growth decades ago, last flavor I learned was C99. Fixing it in c++ is weird though because you have tools that make pointers kinda silly for most tasks.


The solution is to NOT make a C library for users where they have to deal with the pointer problem. Make a C++ library and let a destructor handle the memory issues, or use strings which do it for you. You want to have the power of C++ in C, and the language lacks the tools you want. You want to have the C in c++, and you can DO that, but its not really the best solution because we have tools that make hands-on pointer stuff not worth doing. I can show you, but its bad code.

if there is some weirdness that you want the C code under the hood you can do that too, and wrap the final thing in c++ just to tap the destructor functionality that C lacks, nothing else, the rest can be C. Then the C users would have to delete the memory hands-on, and c++ users would not -- with the same code base apart from the c++ having an extra file that wraps it up.

wasting a few bytes for fixes sized strings is harmless. Your computer probably has *gigabytes* of memory. that's 1,073,741,824 characters each, and my home pc has 32 times THAT. That's an awful lot of letters. Wasting even 100 letters per string, you still need to have 10s of millions of strings before you would even begin to notice the waste. There are programs that handle this kind of data, but is yours really one of them?

you can also solve your problem with a memory manager. But its a royal pain in the backside, and it will also waste memory, it just wastes less by reusing instead of allocate and release.
Last edited on
Are arithmetic expressions and logical expressions (that can be compiled compile time) also stored in ROM like how string literals are? eg. is 2*2*2 stored as 8 in ROM?

Pointers can point to ROM? They can point to string literals.. Can pointers point to evaluated arithmetic expressions on ROM then?

Is there a limit to how much ROM you can store or that just depends on the device' storage?
jonnin wrote:
wasting a few bytes for fixes sized strings is harmless. Your computer probably has *gigabytes* of memory.

The stack is normally much more limited in size so, unless you dynamically allocate the array, it could be a problem if you are careless.

Grime wrote:
Does how much ROM you can have depend on storage capability of the device?

The use of read-only memory is only an implementation detail. The C++ standard does not guarantee that it's being used. It's just an extra protection in case you accidentally modify the data.

In this situation the read-only memory is normally just regular memory that as been marked read-only (not some special piece of hardware), so that if the hardware detects that the program tries to read to this area it will generate an interrupt (which will normally cause your program to crash).

Grime wrote:
Are arithmetic expressions and logical expressions (that can be compiled compile time) also stored in ROM like how string literals are? eg. is 2*2*2 stored as 8 in ROM?

The expression will be compiled into machine instructions which is normally stored in a read-only memory region. The 8 would just be part of those instructions. https://godbolt.org/z/EhFfKF

Grime wrote:
what do people who have to save on memory do? If they had to store different string literals in one string variable?

You shouldn't worry about string literals staying alive for the whole duration of the program. The string literals need to be stored somewhere in memory (this is also true for the machine instructions).

1
2
3
4
5
6
7
8
9
10
// p points to the locaton where "abc" is stored (it has to be stored somewhere)
const char* p = "abc";

{
	// str will be a copy of the string literal "123"
	char str[] = "123";

} // str goes out of scope and is destroyed, but the string literal "123"
  // is still stored in memory (it has to be, otherwise how could you 
  // initialize str next time this code is executed?) 
Last edited on
So "abc" is stored in RAM itself but marked as read-only??

char str[] = "123";
str = "321";

do both "321" and "123" exist in memory apart from the str[], or is "123" overwritten?

Would using characters to initialize over string literal have any kind of advantage be it small (single characters are rvalues right, as opposed to string literals which apparently are lvalues)?
Where can I learn assembly that C++ uses?

Last edited on
So "abc" is stored in RAM itself but marked as read-only??

Yeah, sort of, except that it doesn't have to be the stored in the RAM all the time. If the computer runs out of RAM the OS might start swap things to the hard drive so the physical location of the data could vary. It doesn't really affects your program (except that it will probably run much slower).

char str[] = "123";
str = "321";

The second line is a compilation error. You cannot assign to arrays. You would have to use strcpy or something like that.

do both "321" and "123" exist in memory apart from the str[], or is "123" overwritten?

No the string literal "123" would not get overwritten (pretending the code is valid). str is not a string literal. It's just a local variable, an array of size 4 that is initialized to have the same content as the string literal "123".

Would using characters to initialize over string literal have any kind of advantage be it small (single characters are rvalues right, as opposed to string literals which apparently are lvalues)?

Probably not, but it depends on what the compiler decides to do of course.

Where can I learn assembly that C++ uses?

There is no "Standard C++ Assembly". It depends on the hardware.
Compiler Explorer (https://godbolt.org/) is a great tool for checking what assembly various compilers generates. Don't forget to pass optimization flags (e.g. -O2) otherwise the generated assembly instructions will be very suboptimal.
Last edited on
Is this correct?

1
2
3
 str[2];
str[0] = 'h';
str[1] = '\0';

Costs the program 2 bytes of RAM

whereas,
str[2] = "h";
Costs the program 4 bytes of RAM? ("h" = { 'h', '\0' })

So using string literals costs you twice the RAM, so what would somebody who is really restricted on RAM do (and I mean really really)?
Last edited on
See my updates that I made to my previous post. ^

Is this correct?
1
2
3
str[2];
str[0] = 'h';
str[1] = '\0';

Yes, except that you forgot do specify the type (char) of the array elements.

Costs the program 2 bytes of RAM

Yeah the array will be two bytes. How much more memory it cause your program to use is hard to say. Sometimes compilers insert extra padding for various reasons, and the extra instructions would also take up some memory, but these things are normally nothing to worry about.

Costs the program 4 bytes of RAM? ("h" = { 'h', '\0' })

Again, hard to say. If the compiler sees that str is never used, or only part of it is used, it might be able to optimize away the array completely.

So using string literals costs you twice the RAM

If you don't plan to modify the string there is no reason to use an array to store a copy of the string literal. Just use a const char* instead. And, even if you store an exact copy it would only store the copy until it goes out of scope.

so what would somebody who is really restricted on RAM do (and I mean really really)?

You could read string data from files. This might be right choice for translations or large texts that doesn't have to be loaded all the time.
Last edited on
Pages: 12345