C program: returning a pointer

  • Thread starter Math Is Hard
  • Start date
  • Tags
    Program
In summary, the conversation is about returning a pointer from a function and passing it back to the main function. The options discussed are using a pointer-to-a-pointer or a reference-to-a-pointer, and the proper way to return the pointer to the main function is shown. It is clarified that the main function does not have to be prepared to accept the return value, but instead, a place to put the return value should be made. It is also noted that while some compilers may accept it, making the return value from the main function 'void' instead of 'int' is an error.
  • #1
Math Is Hard
Staff Emeritus
Science Advisor
Gold Member
4,652
37
Hello all,
I am stuck on a little problem. I need to figure out how to return a pointer from a function I am calling and pass it back to the main function. For instance in the example below, I print the address of the first character of a string and then I call a function which increments the pointer to the next address and then prints that address. What I would really like to do is pass the pointer out of the called function and then have the main function print the address of the returned pointer.

PHP:
#include <stdio.h>
void nextaddress(char* s);
void main(void)
{
     char thestring[] = "Jessica";
     printf("now pointing to address %p \n",thestring); //print 1st addr
     nextaddress(thestring);
}

void nextaddress(char* s)
{
     s++;
     printf("now pointing to address %p \n",s); //print next addr
}

I had tried previously set up the main function to take a returned char:
void main(char)
and to set up my nextaddress() function to return a char:
char nextaddress(char* s)
to return s from the nextaddress() function:
return s;
but I didn't have any luck.
What's the proper way to return the pointer to main().

Thanks. :smile:
 
Physics news on Phys.org
  • #2
There are two ways to do it -- use a pointer-to-a-pointer, a char**, or use a reference-to-a-pointer, a (char*)&.

Do you know how to use references yet?

- Warren
 
  • #3
Hi Warren,
We haven't covered references yet. I just went and looked it up in my book and it's a couple of chapters down the road. It says something about using a defining declaration vs. a referencing declaration which I didn't quite comprehend. Should I try that pointer-to-a-pointer method?
umm.. char** means pointer to a pointer, I assume? Thx!
 
  • #4
Yep, you can do something like this:

PHP:
#include <stdio.h>
void nextaddress(char* s);
void main(void)
{
     char thestring[] = "Jessica";
     printf("now pointing to address %p \n",thestring); //print 1st addr
     nextaddress(&thestring);
}

void nextaddress(char** s)
{
     (*s++);
     printf("now pointing to address %p \n",*s); //print next addr
}

- Warren
 
Last edited:
  • #5
Of course you could also just do this:

PHP:
#include <stdio.h>
void nextaddress(char* s);
void main(void)
{
     char thestring[] = "Jessica";
     printf("now pointing to address %p \n",thestring); //print 1st addr
     thestring = nextaddress(thestring);
}

char* nextaddress(char* s)
{
     s++;
     printf("now pointing to address %p \n",s); //print next addr
     return s;
}

- Warren
 
  • #6
I am still having some trouble. Take a look? Thanks.

PHP:
#include <stdio.h> 
void nextaddress(char* s); //prototype

void main(char* thestring) 
{ 
     char thestring[] = "Jessica"; 
     printf("now pointing to address %p \n",thestring); //print 1st addr 
     thestring = nextaddress(thestring); 
     printf("now pointing to address %p \n",thestring); //print next addr 
} 

char* nextaddress(char* s) 
{ 
     s++; 
     return s; 
}

Here are my errors:

error C2082: redefinition of formal parameter 'thestring'
error C2120: 'void' illegal with all types
error C2040: 'nextaddress' : 'char *(char *)' differs in levels of indirection from 'void (char *)'
 
  • #7
Math Is Hard said:
Here are my errors:

error C2082: redefinition of formal parameter 'thestring'
error C2120: 'void' illegal with all types
error C2040: 'nextaddress' : 'char *(char *)' differs in levels of indirection from 'void (char *)'
Sorry, I should have tried to compile it before posting it. :redface:

1) Use "char* thestring = "Jessica";" to create your original string.

2) I'm not sure why, but in your latest code, the main function is taking an argument of type char*. It should still be void.

2) Your prototype for nextaddress must match the declaration. In the prototype, the return type is void, while in the declaration, the return type is char*.

Try this:

PHP:
#include <stdio.h>
#include <string.h>

char* nextaddress(char* s); //prototype

void main(void)
{
     char *thestring = "Jessica";
     printf("now pointing to address %p \n",thestring); //print 1st addr
     thestring = nextaddress(thestring);
     printf("now pointing to address %p \n",thestring); //print next addr
}

char* nextaddress(char* s)
{
     s++;
     return s;
}

- Warren
 
  • #8
Thanks - that worked great!

chroot said:
2) I'm not sure why, but in your latest code, the main function is taking an argument of type char*. It should still be void.

I was thinking that if I was returning something from the called function back to the main() function that I would have to prepare main() to take the thing that is returned as an argument in order for it to be used. I think that's where I got confused.

-Jessica
 
  • #9
You don't have to prepare the main function itself to accept a value returned by some function -- all you have to do is make a place to put that return value. You're already putting the return value of nextaddress() into the thestring variable, so you're all set.

If you modified the calling of the main() function itself, you'd be changing its interaction with the operating system -- after all, the operating system is what called the main() function for you to start your program running. Any arguments accepted by main() come from the OS, and any return value goes back to the OS.

Think about a program like "cd," which changes directories when you're working on the command line. The cd program has to accept a string from the operating system, so when you type "cd myfolder" it can get ahold of the name "myfolder." It also returns a value back to the operating system indicating whether or not the operation was successful.

- Warren
 
  • #10
wow! I had really been mixed up on this. Thanks for the clarification.
 
  • #11
Nitpick:
While some compilers accept the practice, making the return value from main 'void' rather than 'int' is an error. The practice has unfortunately been used in several beginning C textbooks, and thus people adopt the habit when they're programming under controlled conditions where the error is unlikely to cause problems. However, the operating system will always try to collect the value returned by main, and there are many circumstances where this value needs to be passed to another process in the computer. Returning void most often causes a random value to be passed along. As the convention is that a process that terminates normally returns zero (so non-zero values imply an error occurred), other processes are most likely to be confused by the value they receive.

Function arguments and return values:
A C function can be considered a series of instructions. If a function is declared so that it accepts arguments, these instructions can expect values corresponding to the arguments to available. Thus when a function is called, the system sets up locations for the arguments and loads in the values presented to the function call. While the function is executing, these locations exist in the same way that variables declared inside the function exist, and have no special properties.

When the function terminates it throws out all the information about the arguments and local variables, and puts the return value in the place that the caller expects to find it.

There is no need to "prepare a place" for a return value to go back to. Of course, if the value is one you want to use you do need to capture it somehow as it is returned.

Examples:
printf("Some boring text.\n");​
printf (in most versions) returns the number of characters printed. However, most of the time this information is not needed. Thus the printf call appears on a line by itself, and when it returns the value is discarded and the system moves on and executes the next statement.
x = cos(theta);​
In this case, when the return value of cos(theta) shows up the system knows that the statement has more to do, i.e. that it must take the value and store it in x. However, setting a variable in this fashion is like a function in that after storing the value, the stored value is again placed in the spot for a return value. For the given statement, there is nothing more to do though, so this time the value is discarded.
x = log(cos(theta));​
This statement has another layer. The value from cos(theta) is captured by the call to log. The call to log then returns a value to be stored. The storage operation returns the value again. This final value is discarded.

It's possible that most (or all) of this is obvious to you. My apologies if I'm misreading the substance of the confusion you expressed above.
 
  • #12
hi plover,
now that I think about it, it was confusing to me sometimes when the text used some examples with

void main(void)
{
}

and then other examples with

int main(void)
{
return 0;
}

I couldn't quite figure out if it really mattered if you did it one way or the other. I am still naive enough that I just say "Hey, the program runs - must be the right way to do it!"
anyway, thanks, my rain-bird friend! I appreciate your taking the time to respond.
:smile:
 
  • #13
If you're feeling masochistic, you could try to predict the output of this version of the program. :wink:

PHP:
#include <stdio.h>
#include <string.h>

char* nextaddress(char* s) { return ++s; }

int main(void)
{
     char *thestring = "Jessica";
     printf("string starts as: %s\n", thestring);
     printf("pointer to address: %p\n", thestring);
     printf("pointer to address: %p\n", thestring++);
     printf("pointer to address: %p\n", nextaddress(thestring));
     printf("pointer to address: %p\n", (thestring = nextaddress(thestring)));
     printf("string is now: %s\n", thestring);
     return 0;
}
 
  • #14
heck, I didn't even know you could write things that way! :eek:
 
Last edited:
  • #15
new problem - stuck on 2D arrays

I am having trouble figuring out what to do with these instructions..

"Write a declaration, including arguments and result, for a two-dimensional version of strlen, that is, a function that receives an array of pointers to char and an array of size_t integers, and an int that specifies the number of elements in each array. (You don't need to write the actual function.)"

I am not getting the hang of two-dimensional arrays.

I had tried something like this:
PHP:
# include <stdio.h>
void TwoDimStrlen(char *ptr,size_t,int n);
int main(void)
{
     const char *ptr[6] = {'H','e','l','l','o','\0'}; 
     int size_t[] = {1,2,3,4,5,6};
     int n = 6;
     return 0;
}

void TwoDimStrlen(char *ptr,size_t,int n)
{
     //..function code goes here…
}

but I am getting more and more lost and creating a bigger mess. :grumpy: Thanks for any advice.
 
  • #16
Math Is Hard said:
I am having trouble figuring out what to do with these instructions..

"Write a declaration, including arguments and result, for a two-dimensional version of strlen, that is, a function that receives an array of pointers to char and an array of size_t integers, and an int that specifies the number of elements in each array. (You don't need to write the actual function.)"
I'm not exactly sure what's going on here either. I have no idea what they're asking for.

I had tried something like this:
PHP:
# include <stdio.h>
void TwoDimStrlen(char *ptr,size_t,int n);
int main(void)
{
     const char *ptr[6] = {'H','e','l','l','o','\0'}; 
     int size_t[] = {1,2,3,4,5,6};
     int n = 6;
     return 0;
}

void TwoDimStrlen(char *ptr,size_t,int n)
{
     //..function code goes here…
}
There's something wrong with your "const char *ptr[6] = {...};". What you've done there is created an array with 6 pointers-to-chars. Or, in other words, an array with 6 strings. Now, the first element in you array, then, should be a pointer-to-char, but it's just a char, namely 'H'. This isn't right (as far as I can tell). I would tell you what I think you should do, but I'm not clear on your instructions, so I don't know what to say. Actually, I don't even know why you have a main function (I guess it's just for trial purposes?).
 
  • #17
The first arugment must be a char**, since the function is taking an array of char pointers. Think about what this means. A char** is the same as a (char*)*. A char* is a pointer to one or more chars, so a char** is a pointer to one or more pointers to one or more chars. :wink:

The second argument is an array of size_t objects -- in other words, a size_t*. Presumably, these integers represent the lengths of the arrays pointed to by the first argument.

The third argument is the number of those arrays.

The function should return a size_t*, which is an array of size_t objects.

- Warren
 
  • #18
Thanks, AKG and Warren. I knew I had this completely jacked-up, but I didn't even know where to start to fix it.
I am going to work on this some more now.
 

1. What is the purpose of returning a pointer in a C program?

Returning a pointer in a C program allows the function to pass back a memory address to the caller, which can then be used to directly access or modify the data stored at that location.

2. How is a pointer returned in a C program?

A pointer can be returned in a C program by using the return keyword followed by the pointer variable. It is important to ensure that the pointer being returned points to valid memory in order to avoid any errors.

3. Can a function return multiple pointers in a C program?

Yes, a function can return multiple pointers in a C program by using the return statement multiple times, each time with a different pointer variable. Alternatively, a function can also return a single pointer to a struct or array that contains multiple pointers.

4. What is the difference between returning a pointer and returning a value in a C program?

Returning a value in a C program passes a copy of the value to the caller, while returning a pointer passes the actual memory address to the caller. This means that returning a pointer allows the caller to directly modify the data at that address, while returning a value does not.

5. Are there any potential risks involved in returning a pointer in a C program?

Yes, returning a pointer in a C program can be risky if the pointer is not properly initialized or if it points to invalid memory. This can lead to errors or unexpected behavior in the program. It is important to ensure that the pointer being returned is valid and points to the correct data.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
943
  • Programming and Computer Science
Replies
5
Views
883
  • Programming and Computer Science
Replies
4
Views
733
  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
753
  • Programming and Computer Science
3
Replies
89
Views
4K
  • Programming and Computer Science
Replies
7
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
11
Views
2K
Back
Top