-1

Say i have a char* method that returns a char array. How mould i set another char array equal to that return value? For example, here's the char* method:

char* work(int num){
    char buf[32];
    sprintf(buf, "%d", num);

    return buf;
}

what do I need to put in the main method to use the returned value? I've tried

int main() {
    char rValue[32] = work(5);
}

but i get "error: array initializer must be an initializer list or string literal"

and

int main() {
    char rValue[32];
    rValue = work(5);
}

gives me "error: array type 'char [32]' is not assignable".

I know that the solution is probably extremely simple, but i'm lost. How can i access the returned value?

Tim
  • 41,901
  • 18
  • 127
  • 145
user3591210
  • 83
  • 1
  • 2
  • 5

4 Answers4

4

What you want to do is pass the rValue using a pointer.

I'm not entirely sure on what you are trying to achieve but my amendments below allow for compilation with no errors on gcc.

What you are doing is passing the address of the first element of your rValue array into work. There is no need for a return as you are directing working on the original data. This is similar to what some languages have when they "pass by reference"

#include <stdio.h>

void work(int num, char *rValue) {
    sprintf(rValue, "%d", num);
}

int main() {
    char rValue[32];
    work(5, rValue);
}
Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
Arcana
  • 239
  • 5
  • 13
  • 2
    Nice, simple and elegant – Mohit Jain May 08 '14 at 16:52
  • 3
    You should also pass the size of the buffer, to allow the function to check this (by for example using `snprintf()`) and avoid overflowing the buffer. Thus making the function return an `int` to be able to tell the caller its outcome whould be the next level of improvement. – alk May 08 '14 at 16:59
  • Thanks for the help! Your example is definitely good to know, unfortunately i can't stray from how the starter code is set up. The code that i posted is set up similarly to the starter code and i just wanted to get this concept down. – user3591210 May 08 '14 at 17:08
1

You cannot return an array from a function. That is because the array buf is local to the function work. The array buf goes out of scope after the function returns and accessing it thereafter invokes undefined behaviour.

Arrays are not first-class objects in C in the sense that you cannot pass an array to a function or cannot return an array from a function. What actually gets passed or returned is a pointer to the first element of the array. This is also stated as the array decays to a pointer to its first element.

You should allocate your array dynamically so that it is not destroyed until you free the memory allocated.

char *work(int num) {
    char *buf = malloc(32);

    // check the result of malloc
    // in case it fails
    if(buf == NULL) {
        printf("malloc failed to allocate memory\n");
        return NULL;
    } 

    // make sure that buff is large enough 
    // to contain num else sprint will overrun
    // buf causing undefined behaviour
    sprintf(buf, "%d", num);

    return buf;
}

And your main should be

int main(void) {
    char *p = work(5);
    if(p == NULL)
        return 1;

    printf("%s\n", p);
    free(p);
    return 0;
}
ajay
  • 9,402
  • 8
  • 44
  • 71
1

Firstly, you cannot return a local array like that. It will go out of scope and the values may become garbage. What you need to do is to dynamically allocate it first. Once you do that, you're safe to return it.

char* work(int num){
    char *buf = malloc(sizeof(char)*32);
    sprintf(buf, "%d", num);

    return buf;
}

Now, to receive a pointer, you'll need another pointer variable. Not an array.

int main() {
    char *rValue = work(5);
}

Finally, you need to free the memory you've allocated so that it can be used in future.

int main() {
    char *rValue = work(5);
    free(rValue);
    return 0;
}

See more about malloc and free.

HelloWorld123456789
  • 5,299
  • 3
  • 23
  • 33
  • Do you really need to call malloc to return 32 bytes. – this May 08 '14 at 16:47
  • 1
    I see no problem there. – HelloWorld123456789 May 08 '14 at 16:47
  • It would be more common to declare a global variable for such a simple example but it is important to understand what steack and heap is and when it is freed! See here: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap – Matthias May 08 '14 at 16:49
  • @Matthias That would be even worst. A lot of people can't return bytes without resorting to malloc. – this May 08 '14 at 16:51
  • 1
    @self Please explain that. Sometimes global variables are good (not often). – Matthias May 08 '14 at 16:52
  • Any why is this downvoted? Is there anything **wrong** I've written? – HelloWorld123456789 May 08 '14 at 16:52
  • For the _one_ who downvoted please read this: http://stackoverflow.com/help/privileges/vote-down – HelloWorld123456789 May 08 '14 at 16:54
  • Thanks for the replies and help! Also, to clear up some confusion about what i'm doing or why i went about setting up the example that way: it's just a simplified part of what i need to do for an assignment. I just needed to get this concept down so that i could wright the actual function. – user3591210 May 08 '14 at 17:03
0

char buf[32]; is a local variable. its memory will be freed after function execution. You should use malloc to assign memory from the heap to a char pointer. You can copy arrays with memcopy. In case you want to copy one array to another work with char * not char (pointer).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>  
char* work(int num){
    char *r = (char*)malloc(sizeof(char)*32);
    sprintf(r, "%d", num);
    return r;
}

int main() {
    char *rValue = NULL;
    rValue = work(5);
}
Matthias
  • 1,386
  • 3
  • 24
  • 59
  • 1
    Do `free` the rValue memory at last – Mohit Jain May 08 '14 at 16:47
  • 1
    Not required when program ends (in most cases like on windows the OS does the job). – Matthias May 08 '14 at 16:48
  • 2
    I agree, but freeing a memory is always considered a good excercise. What if the code block moves to another function from `main` in future. When you free a memory or close a file or release a mutex shows author knows what memory he is using. I advocate one should free the dynamically allocated memory. May be good for the small project or demo program, but **dangerous** for big projects. – Mohit Jain May 08 '14 at 17:00
  • 1
    In C there is no need to cast `malloc/Calloc/realloc`, nor is it recommended in any way: http://stackoverflow.com/q/605845/694576 – alk May 08 '14 at 17:08