pass pointer by reference

H

HSeganfredo

Folks,

I want to write a init string function that mallocs an area, fills it
with a char, sticks a NUL char in the last position and returns it to
the user.

So far I noticed that my implementation always works over a NEW memory
area, and not over the ORIGINAL pointer area, so the initial string
area is untouched, the pointer is not update to refer to the new
initiated area...

What is going on? See my code below...

int main(){
char *string;
initstring(string, '\0', 14); /* create a string filled with NUL
and a extra NUL at position 15 */
/* if I check *string here, it is untouched since the 1st statement
*/
}

void initstring(char *array, char c, unsigned int size){
array = malloc((size + 1)* sizeof(char));
int i;

for(i=0;i<size;i++){
/* array = c; array indexing */
*array = c;
array++;
}
/* array[size+1] = '\0'; array indexing */
*array = '\0';
}

So, why "*array" always get into the function initstring with a
diferent value (memory address) than when the initistring() function
is called (according)?

My environment: Eclipse + CDT + Cygwin (Win32)
 
A

André Gillibert

HSeganfredo wrote:

[...]
int main(){
char *string;
initstring(string, '\0', 14); /* create a string filled with NUL
and a extra NUL at position 15 */
/* if I check *string here, it is untouched since the 1st statement
*/
}
[...]
void initstring(char *array, char c, unsigned int size){
array = malloc((size + 1)* sizeof(char));

You pass a *copy* of the pointer to the initstring function.
The modification of array in initstring won't affect the string variable
in main.

You must pass a pointer to pointer, if you want to modify the pointer.

initstring(&string, '\0', 14);
/* ... */
void initstring(char **parray, char c, unsigned int size){
char* array;
array=*parray = malloc((size + 1)* sizeof(char));

BTW, you should respect the sixth commandment for the C programmer:
"
If a function be advertised to return an error code in the event of
difficulties, thou shalt check for that code, yea, even though the checks
triple the size of thy code and produce aches in thy typing fingers, for
if thou thinkest ``it cannot happen to me'', the gods shall surely punish
thee for thy arrogance.
"

You must check the return value of malloc()!
 
M

Martin Wells

initstring(string, '\0', 14);


As someone has already said, you have to pass the address of the
pointer, i.e. a pointer to a pointer.

Really though, I'd just return a pointer from the function:

Unchecked, untested code. . .

char *const initstring(char const c,size_t const len)
{
char *const retval = malloc(len + 1);

char *p = retval;
char const *const pnull = retval + len;

while (p != pnull) *p++ = c;

*p = 0;

return retval;
}


I use the const in the return value as an indicator to the programmer
that they might want to hang on to the value.

Martin
 
H

HSeganfredo

Thanks for the "pointers", worked here perfectly.

I started to remember that a pointer reference "func(&ptr)" in the
calling function always implies on a double pointer in the prototype
(**ptr), one contains the original pointer reference (to char in my
case) and another one containing the reference to that pointer. It´s a
somewhat complex subject that makes years I don´t deal with. Thanks.
 
P

pete

void initstring(char *array, char c, unsigned int size){
array =

Whenever you see a function definition,
where a parameter is being overwritten
without being read first, that's a bad sign.
 
W

Willem

Martin wrote:
) char *const initstring(char const c,size_t const len)
) {
) char *const retval = malloc(len + 1);
)
) char *p = retval;
) char const *const pnull = retval + len;
)
) while (p != pnull) *p++ = c;
)
) *p = 0;
)
) return retval;
) }

I find that a very convoluted way to write:

if (retval = malloc(len + 1)) {
memset(retval, c, len);
retval[c] = 0;
}
return retval;


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
D

Denis Kasak

Willem said:
Martin wrote:
) char *const initstring(char const c,size_t const len)
) {
) char *const retval = malloc(len + 1);
)
) char *p = retval;
) char const *const pnull = retval + len;
)
) while (p != pnull) *p++ = c;
)
) *p = 0;
)
) return retval;
) }

I find that a very convoluted way to write:

if (retval = malloc(len + 1)) {
memset(retval, c, len);
retval[c] = 0;

You probably meant retval[len] = 0;
 
W

Willem

Denis wrote:
) Willem wrote:
)> if (retval = malloc(len + 1)) {
)> memset(retval, c, len);
)> retval[c] = 0;
)
) You probably meant retval[len] = 0;
)
)> }
)> return retval;

It's a well-known Law of the Useniverse that any post which is made to
correct/improve upon any piece of language must contain a silly error.

I guess C counts as a language as well for that Law. :)


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
M

Martin Wells

Willem:
I find that a very convoluted way to write:

if (retval = malloc(len + 1)) {
memset(retval, c, len);
retval[c] = 0;
}
return retval;


You're right I shuda used memset... it slipped my mind that there's a
Standard Library function for doing that.

Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top