8
#include <stdio.h>
#include <stdlib.h>

void
getstr(char *&retstr)
{
 char *tmp = (char *)malloc(25);
 strcpy(tmp, "hello,world");
 retstr = tmp;
}

int
main(void)
{
 char *retstr;

 getstr(retstr);
 printf("%s\n", retstr);

 return 0;
}

gcc would not compile this file, but after adding #include <cstring> I could use g++ to compile this source file.

The problem is: does the C programming language support passing pointer argument by reference? If not, why?

Thanks.

5
  • Not related to your question, but for curiosity, what's the use case for passing a pointer as a reference? Commented Dec 1, 2009 at 12:16
  • 1
    @Tristram: if you want the function to be able to modify the pointer, and have the modification propagate beyond the scope of the function. Commented Dec 1, 2009 at 12:17
  • If you want to perform malloc of strings in a function that does not free that memory then you could consider using valgrind or equivalent tool to test for memory leaks. Commented Dec 1, 2009 at 12:18
  • 2
    A reference is a way of confusing programmers as to what is really happening. If you discipline your approach to pointers you'll find that references are not necessary. When dealing with a reference a compiler is taking actions on an object and managing the indirection for you. Commented Dec 1, 2009 at 12:25
  • 1
    PP: Gross oversimplification of references; any feature can be abused. Commented Jan 13, 2010 at 15:07

6 Answers 6

29

No, C doesn't support references. It is by design. Instead of references you could use pointer to pointer in C. References are available only in C++ language.

Sign up to request clarification or add additional context in comments.

Comments

20

References are a feature of C++, while C supports only pointers. To have your function modify the value of the given pointer, pass pointer to the pointer:

void getstr(char ** retstr)
{
    char *tmp = (char *)malloc(25);
    strcpy(tmp, "hello,world");
    *retstr = tmp;
}

int main(void)
{
    char *retstr;

    getstr(&retstr);
    printf("%s\n", retstr);

    // Don't forget to free the malloc'd memory
    free(retstr);

    return 0;
}

2 Comments

Don't cast what malloc() returns. If you've included stdlib.h, it does absolutely nothing. If you haven't, it hides that fact.
As malloc returns void* I find it good practice to cast it explicitly to the required type instead of relying on implicit conversions. If stdlib.h is not included, casting doesn't hide that fact - the compiler will warn you that malloc has not been declared.
5

Try this:


void
getstr(char **retstr)
{
 char *tmp = (char *)malloc(25);
 strcpy(tmp, "hello,world");
 *retstr = tmp;
}

int
main(void)
{
 char *retstr;

 getstr(&retstr);
 printf("%s\n", retstr);

 return 0;
}

2 Comments

Don't cast the return value of malloc. It can hide a failure to #include <stdlib.h> (which you did forget in the code above). See c-faq.com/malloc/mallocnocast.html Also, don't forget to check the return value of malloc.
Wow, some people struggle to see the difference between a proof of concept test routine and production code! It was obvious this was a rough-and-ready test routine because there was no corresponding free but I guess some people miss the obvious!
2

This should be a comment but it is too long for a comment box, so I am making it CW.

The code you provided can be better written as:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
getstr(char **retstr)
{
    *retstr = malloc(25);
    if ( *retstr ) {
        strcpy(*retstr, "hello,world");
    }
    return;
}

int
main(void)
{
    char *retstr;

    getstr(&retstr);
    if ( retstr ) {
        printf("%s\n", retstr);
    }
    return 0;
}

Comments

1

There is an interesting trick in libgmp which emulates references: typedef mpz_t __mpz_struct[1];

and then you can write like this:

mpz_t n;
mpz_init(n);
...
mpz_clear(n);

I would not recommend to use this method, because it may be incomprehensible for others, it still does not protect from being a NULL: mpz_init((void *)NULL), and it is as much verbose as its pointer-to-pointer counterpart.

Comments

0

C lang does not have reference variables but its part of C++ lang.

The reason of introducing reference is to avoid dangling pointers and pre-checking for pointers nullity.

You can consider reference as constant pointer i.e. const pointer can only point to data it has been initialized to point.

1 Comment

The other difference (besides the syntactic ones) is that references cannot be null.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.