1

Hi I am pretty new to C and was wondering how to return an entire array. For example I have this function here.

char* foo(int x)
{
    char *num = (char*)malloc(x*sizeof(int));
    
    num[0] = '1';
    num[1] = '2';
    num[2] = '3';
    num[3] = '4';

    return num;
    
}  

I realized that when I return num it only returns the first index of num. But is there any way to return the whole array, 1234? Any help will be greatly appreciated!

Octo Rise
  • 19
  • 1
  • It returns a pointer to the first element of the array which you can use to access the rest, assuming you know how many elements were allocated. Perhaps you can describe in greater detail the issue you're having and expand your code example to demonstrate it. – Retired Ninja Jan 30 '22 at 02:15
  • The general-purpose answer to "how do I return an array in C?" is well addressed at: https://stackoverflow.com/q/11656532/ . But for the `foo()` you have tried to implement here, three points: 1) this should work fine, try accessing indexes [0], [1] etc. of the return value; 2) you're malloc'ing `x*sizeof(int)`, why isn't this `x*sizeof(char)`?; 3) if you're malloc'ing in a function, make sure it's really clear in your documentation/comments and that any callers of `foo()` then `free()` the memory to avoid memory leaks. This is kind of risky for introducing memory leaks. – Laogeodritt Jan 30 '22 at 02:29

2 Answers2

0

Since the foo() function returns a pointer, you can see that all values are printed when you use the %s format specifier. The display() function prints the data in the memory area pointed to by the pointer as characters.

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

char* foo(int x)
{
    char* num = (char*) malloc((x + 1) * sizeof(char));
    
    for(size_t i = 0 ; i < x ; ++i)
        num[i] = i + 1 + '0';
    num[x] = '\0';
    
    return num;
}

void display(char *array, size_t size)
{
    for(size_t i = 0 ; i < size && array[i] != '\0' ; ++i)
        printf("array[%ld]: %c\n", i, array[i]);
}

int main()
{
    const size_t size = 4;
    char *result = foo(size); 
    
    printf("%s\n", result);
    display(result, size);
    
    return 0;
}

Output:

1234
array[0]: 1
array[1]: 2
array[2]: 3
array[3]: 4
Sercan
  • 4,739
  • 3
  • 17
  • 36
  • This prints the array contents as a string without ensuring it is terminated with a null character. – Eric Postpischil Jan 30 '22 at 02:23
  • Hi thank you very much, your code was exactly what I was looking for. But just one quick question, can you explain why you + '0' in the foo for loop? I realize it doesn't work without it but I'm not exactly sure what it does. Thanks in advance! – Octo Rise Jan 30 '22 at 23:25
  • @OctoRise When you initialize an array manually, the compiler guarantees that the last element will be `'\0'`. However, when allocating memory with `malloc()`, assigning `'\0'` to the data in the last index helps avoid errors. – Sercan Jan 30 '22 at 23:34
  • @OctoRise For example, in the above program, instead of assigning `num[x] = '\0'` in `foo()`, instead of assigning `num[2] = '\0'`, 3 elements (two data members and `'\0'`) are odd while printing the data to `stdout`. – Sercan Jan 30 '22 at 23:38
  • @Sercan Okay so I tried adding `+ '0'` similar to how you did this `num[i] = i + 1 + '0';`, but I think the `+ '0'` interfered with my results. For example I malloced an array called num and did this: `num[0] = 1+2;` which sets num[0] to 3 which is perfect, but when I do `num[1] = 1+2 + '0'`, num[1] is equal to 51. Sorry if my question is convoluted but essentially, how do i make `num[1] = 1+2+ '0'` equal to 3? Thanks. – Octo Rise Jan 31 '22 at 00:17
  • @OctoRise I think I got it wrong. The statement you refer to is used to convert the data in int type to the data of the char type. For example, the statement of '0' + 1 is equal to the character of '1'. ie used to achieve the desired character in the ASCII table. – Sercan Jan 31 '22 at 00:29
  • @OctoRise The '3' character of the ASCII table is 51. Since the num sequence is defined, you will see the output of 51 if the %d format specifier is used instead of %c format specifier in the printf() method. In addition, the statement of "1 + 2 + '0'" is not equal to the integer of 3; this statement is equal to '3' characters. – Sercan Jan 31 '22 at 00:39
  • @Sercan Oh okay thank you for clarifying. So upon playing with my code even more, I somehow made it so that `num[0] = 2 + 1 + '0';` equals 3 but I notice that when the numbers are greater than 9 for example `num[1] = 5 + 5 + '0';` it equals to ASCII representation, `:`. But what I want is for num[1] to equal 10. Is that possible? – Octo Rise Jan 31 '22 at 10:18
  • @OctoRise You can do this more easily if you define the "num" pointer of type char* as an int*. I didn't want to change this since in your question the "num" pointer is defined as a char* type. – Sercan Feb 04 '22 at 21:07
0

See if you are new to C, then learn it first do some googling and research. If you don't find anything then read some theory of a similar topic for examples (How to return an array in C?). After that some error is happening in your code then you can ask it on stackoverflow.

By the way your should be like:

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

char *foo(int x); // fix prototype errors
char *foo(int x)
{
    char *num = (char *)calloc(x + 1, sizeof(char)); // we added +1 to append the null terminating character in `num`
    for (size_t i = 0; i < x; i++)
        num[i] = (char)(i + 48);
    return num;
}

/* @returns no. of character written on stdout */
int print_foo(const char *num); // fix prototype errors
int print_foo(const char *num)
{
    if (num)
    {
        size_t z = 0;
        for (size_t i = 0; i < num[i] != '\0'; i++)
           z +=  fprintf(stdout, "num[%lu] = %c\n", i, num[i]);
        return z;
    }
    return -1;
}

int main(void)
{
    char *num = foo(10);
    print_foo((const char *)num);
    free(num); // free any heap allocated resources before exiting the application
    return 0;
}
Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23