Hi Lim,
can somebody help me understand how char * work?
char * s1;
s1 = "assign a value";
s1 = "assign another value"; //does c auto deallocate storage and
reallocate a longer one for this assignment?
I don't think you understand this: You are NOT copying the value
"assign a value" into the memory that s1 points to.
Instead, you are declaring a buffer in memory that contains the value
"assign a value" -- basically, you're creating an /unnamed variable/ in
memory... a space in the computers memory that will contain the words
"assign a value". Like any space in memory, it has an address.
When you do s1 = "assign a value", you're assigning that address to s1,
which is a pointer.
Then when you have "assign another value", it's a different buffer,
located in a completely different spot in the computers memory. When
you do s1 = "assign another value", you're changing where s1 points. It
no longer points to the address of "assign a value", but instead, it
points to "assign another value". The original "assign a value" is
still there, it's just in a different spot in memory.
In RPG terms, you're doing this:
D foo s 14a inz('assign a value')
D bar s 20a inz('assign another value')
D s1 s *
s1 = %addr(foo);
s1 = %addr(bar);
RPG doesn't let you have an unnamed space in memory like C does, so I
had to assign the names "foo" and "bar". But, other than that, this
code works the same way. It changes the pointer (s1) to point to one
buffer, then switches it to the other buffer.
The original "foo" buffer is still there -- you've just changed s1 to
point elsewhere.
So, no, C doesn't automatically deallocate or reallocate or anything
like that. All of the constants/literals in your program are set up in
memory when your program starts, and all you're doing is switching the
pointer to point to those spots in memory. These constants stay in
memory until the activation group ends.
If you wanted to allocate/deallocate memory you'd probably do something
like this, instead:
s1 = malloc(strlen("assign a value") + 1);
strcpy(s1, "assign a value");
s1 = realloc(s1, strlen("assign another value") + 1);
strcpy(s1, "assign another value");
You have to use strcpy (or memcpy, or sprintf, or another similar
function) to assign a string to a given location in memory. Setting a
pointer equal to a literal won't do it (in C )
hope that makes sense.
char * s1
int myInt = 10;
sprintf(s1, "test %i", myInt); //why is s1 contains *null after this
assignment?
This is VERY DANGEROUS code. Here you have a pointer (s1) that's not
set to any particular space in memory. Unlike RPG, C does *NOT*
guarantee that the pointer's starting value will be NULL. Under most
circumstances it will be null, but you could potentially get unlucky and
have it be set to a valid spot in memory. The sprintf() function then
tries to copy data to that memory.
Essentially, you're doing the equivalent of the following RPG code:
D s1 s *
D foo s 20a based(s1)
/free
s1 = <some random value>;
foo = 'test ' + %char(myInt);
It sets an unspecified place in memory to the value 'test n'. Not a
good idea.
If you're "lucky", s1 will be NULL, and sprintf() should fail.
sprintf() should return -1, to indicate that it failed.
If you want that code to work properly, you need to first change s1 so
that it's pointing to a place in memory. You can do that by pointing to
an existing space in memory, or by allocating more memory and pointing
to the allocated space.
s1 = malloc(20);
sprintf(s1, "test %d", myInt);
Then, remember to call free() to free up the memory. Alternately, have
the system provide memory...
char s1[20];
sprintf(s1, "test %d", myInt);
In this case, the system automatically allocates 20 bytes for you, and
automatically frees it when the procedure ends, so you don't have to
call malloc/free. Much like the way variables work in RPG -- except
that sprintf() won't do any sort of bounds checking. If you try to
write data larger than 20 bytes to s1, it'll overflow into the next area
of memory (however, as far as I can see, that sprintf() never uses more
than 16 bytes...)
Hopefully it should be apparent at this point that s1 was set to NULL
because that happened to be the value before you called sprintf(), and
because you never pointed s1 at valid memory.
As an Amazon Associate we earn from qualifying purchases.