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.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available here. If you have questions about this, please contact [javascript protected email address].