简体   繁体   中英

C - using memcpy in function to assign value instead of return

Playing around and trying to learn how arrays in C work, and just how C works in general. I wanted to make a function that returned a 2 element array and assign that array to a variable. first I did;

int make_array(int i) {
   int out[2] = {i, i + 1};
   return (int) *out;}

int main(void) {
    int arr[2] = { make_array(68) }; // should be {68, 69}
    for (int i = 0; i < 2; i++) {
        printf("%d, ", arr[i]);}
    return 0;

>> 68, 0,

This was the only way I could find to write it without throwing an error, and it output 68, 0, instead of 68, 69,. So I tried this;

void make_another_array(int j, void *vp) {
   int out[2] = {j, j + 1};
   memcpy(vp, &out, sizeof(int) * 2);}

int main(void) {
   int *hotdog_water = malloc(sizeof(int) * 2);
   make_another_array(68, hotdog_water);
   for (int i = 0; i < 2; i++){
       printf("%d, ", hotdog_water[i]);}
   free(hotdog_water); hotdog_water = NULL;
   return 0;}

The function saves the result somewhere instead of returning it. The end result seems to work the way I'd like it to, but not assigning a value from something returned from a function seems hacky. I'm sure there's a better way to do this specific thing, but is there anything fundamentally wrong with doing it this way? What problems would I run into if I wrote to where a pointer was pointing for everything instead of using return? Are there any use cases for copying the results instead of returning it?

Returning data in space provided by the calling routine is normal and common. The standard C library includes several examples, such as:

  • scanf("%d%d", &a, &b) stores values in a and b .
  • frexp(float x, &e) returns one value and stores another in e .
  • fread(array, size, number, stream) provides number values in array .

If you do wish to provide two values through the function-return-value mechanism, you can do this by using a structure:

struct foo { int v[2]; } make_array(int i)
{
    return (struct foo) {{ i, i+1 }};
}

#include <stdio.h>

int main(void)
{
    struct foo x = make_array(68);
    for (int i = 0; i < 2; ++i)
        printf("%d, ", x.v[i]);
    printf("\n");
}

For large structures, a C implementation typically implements the return mechanism just as you suggest with pointers: Where the C code looks like the function returns a structure, in the assembly code, the calling routine provides space for the structure and actually passes a pointer to it as an argument the function. When returning, the function uses that pointer to fill in the return value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM