Quicksorting an array of pointers to structs - c

I'm currently attempting to use the built-in quicksort provided by C in order to sort an array of pointers to structs. I want to sort each element based on a name element within the struct.
Although my debug output of the entire array each time through the comparison function shows me that the function is indeed shifting elements, the end result is not the correct sorted order. Is there something I'm just not seeing here?
typedef struct // The custom data type.
{
char *name;
} Person;
----------------------------
Person **people; // A dynamically allocated array of Person pointers.
int numPeople; // The logical index of people.
int maxPeople; // The current maximum capacity of people.
int compare(const void *a, const void *b) // The comparison function for determining
{ // alphabetic ordering.
const Person *const *p1 = a;
const Person *const *p2 = b;
return strcmp((*p1)->name, (*p2)->name); // Compare alphabetically, return result.
}
void SomeFunction(void)
{
qsort(people, numPeople, sizeof(Person *), compare); // Perform the sort.
}
Thanks for help with this.

I have tested your code and it looks working OK. Here is the code I compiled with gcc 4.5.2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct // The custom data type.
{
char *name;
} Person;
Person **people; // A dynamically allocated array of Person pointers.
int numPeople; // The logical index of people.
int maxPeople; // The current maximum capacity of people.
int compare(const void *a, const void *b) // The comparison function for determining
{ // alphabetic ordering.
const Person *const *p1 = a;
const Person *const *p2 = b;
return strcmp((*p1)->name, (*p2)->name); // Compare alphabetically, return result.
}
void SomeFunction(void)
{
qsort(people, numPeople, sizeof(Person *), compare); // Perform the sort.
}
int main()
{
int iCnt;
maxPeople = 4;
numPeople = 4;
people = calloc(1, sizeof(Person *) * maxPeople);
people[0] = calloc(1, sizeof(Person));
people[1] = calloc(1, sizeof(Person));
people[2] = calloc(1, sizeof(Person));
people[3] = calloc(1, sizeof(Person));
people[0]->name = strdup("Tanya");
people[1]->name = strdup("Alfred");
people[2]->name = strdup("Harry");
people[3]->name = strdup("Oakley");
for(iCnt = 0; iCnt < numPeople; iCnt ++)
printf("[%d] %s\n", iCnt, people[iCnt]->name);
SomeFunction();
for(iCnt = 0; iCnt < numPeople; iCnt ++)
printf("[%d] %s\n", iCnt, people[iCnt]->name);
return 0;
}
The code looks legit and I'm not sure what's wrong. Could you try compiling the code I tested and see if it works?

Can you try with this
int compare(const void *a, const void *b) // The comparison function for determining
{ // alphabetic ordering.
const Person *p1 = *(const Person**)a;
const Person *p2 = *(const Person**)b;
return strcmp((p1)->name, (p2)->name); // Compare alphabetically, return result.
}

Related

Making a generic mode function in C

So I've been trying to make a generic function that calculates the (mathematical) mode of some type.
I've got part of it down but am missing other parts, so it won't compile. I need help on how to fill in those missing parts.
The mode function for integers uses a struct count to determine the element and frequency. Its definition is:
struct count {
int value; // the value of the number
unsigned int freq; // how many times the number has been seen
}
The integer version of mode outputs an array that contains all the ties for the most frequent number along with how many ties there are.
unsigned int mode(int* tiebuf, int* list, size_t listsize)
{
struct count modelist[listsize];
size_t modesize = 0;
// initialize modelist[]
for(int i = 0; i < listsize; i++)
{
int* found = search(list[i], modelist, modesize); // signature: search(key, list, listsize)
if(found == NULL)
{
(modelist[i]).num = &list[i];
(modelist[i]).freq = 0;
modesize++;
}
else
{
(*found).freq++;
}
}
// take the most frequent element (last in modelist)
qsort(modelist, listsize, sizeof(struct count), cmpfreq);
int mode_element = listsize-1;
// see if there are any ties for frequency
size_t tiecount = 1;
for(int i = mode_element-1; i > 0; i--)
{
if((modelist[i]).freq < (modelist[mode_element]).freq)
{
tiecount++; // overshot by 1
break;
}
}
// output the tie as an array
for(int i = 0; i < tiecount; i++)
{
tiebuf[i] = (modelist[mode_element-1-i].number);
}
return tiecount; // returns how many elements are in tiebuf
}
int cmpfreq(const void* obj1, const void* obj2)
{
struct count **t1 = (struct count**)obj1;
struct count **t2 = (struct count**)obj2;
return ( ((*t1)->freq) - ((*t2)->freq) );
}
int cmpnum(const void* obj1, const void* obj2)
{
struct count **t1 = (struct count**)obj1;
struct count **t2 = (struct count**)obj2;
return ( ((*t1)->number) - ((*t2)->number) );
}
int* tiedmode( int* list, size_t listsize, int (*cmp)(const void*, const void*) )
{
// takes the median of all ties in the mode
int ties[listsize];
int tiescount = mode(ties, list, listsize);
qsort(ties, tiescount, cmpnum); // this call doesn't work
// want to call cmpnum with cmp as an argument
// this is why we needed cmpnum
int middle = tiescount/2;
return ties[middle];
}
Now I plan on converting this to a generic notation. The first thing to do is change the definition of
struct count
struct count {
void* object; // some object
unsigned int freq; // how many times that object has appeared
}
The signature for mode must also change to
unsigned int mode(void* tiebuf, size_t tienum, void* list, size_t listsize, size_t objsize, int (*cmp)(const void*, const void*))
The big problem is with the auxiliary function cmpnum and this is where I have trouble. Since qsort requires a function pointer with the signature int (*fnptr)(const void*, const void*), cmpnum also requires that signature. However to compare objects, cmpnum probably also needs another function pointer given by the user on how to compare them. Ideally, the cmpnum function would look like
int cmpnum(const void* obj1, const void* obj2, int (*compare)(const void*, const void*))
{
struct count** t1 = (struct count**)obj1;
struct count** t2 = (struct count**)obj2;
return ( compare(t1->object, t2->object) );
}
So how would I cast a function pointer with 3 arguments to a function pointer with only 2 arguments? Or better yet, how would I solve the problem with the discrepancy between* qsort and cmpnum ?
EDIT: The reason why I need cmpnum in the first place is because of tiedmode. This function takes the mode and outputs the median of the ties. In order to find the median, I have to sort by number. But since this will be made generic, I need the user to let the library know how to sort the object inside struct count.
The comparison function you pass to qsort can only take two arguments.
This is what you do in your top code block.
To do what you want as in your second code block, you'd need to create as many variants of cmpnum as you would have *compare pointers. (e.g. cmpnum_type1, cmpnum_type2, etc.) That's the "clean" way.
Another way [which is slightly messy], is to use your original cmpnum, but have the compare sub-function pointer be a global:
int (*compare) (const void *, const void *);
int
cmpnum(const void *obj1, const void *obj2)
{
struct count **t1 = (struct count **) obj1;
struct count **t2 = (struct count **) obj2;
return (compare(t1->object, t2->object));
}
void
dosort(void)
{
compare = foocmp;
qsort(modelist, listsize, sizeof(struct count), cmpnum);
compare = barcmp;
qsort(modelist, listsize, sizeof(struct count), cmpnum);
}

Using values from a struct in the compare function in qsort() - C99 - Dereferencing pointer to incomplete type

i am fairly new to c and struggling to properly use the C stdlib qsort() function.
This is relevant to education and as such i am only allowed to use C99 and standard libraries if this is important.
I have a list of items taken from a HashTable and put into a HashItem **array but then when sorting this i am struggling with the compare function, i cannot get the correct value out of the struct. I have looked around and seen a few solutions but they all seem to lead to a
[Error] dereferencing pointer to incomplete type
Here is the struct :
typedef struct {
char *word;
int occurences;
} HashItem;
And i am interested in comparing and sorting by the occurences value.
Here is the bit of code which calls the qsort:
int n = array->number_of_values;
HashItem **standard_array = array_getarray(array);
qsort(standard_array, n, sizeof(HashItem*), compare_func);
Here is the compare function:
int compare_func(const void *a, const void *b){
const struct HashItem* aa = (HashItem*)a;
const struct HashItem* bb = (HashItem*)b;
int val_1 = aa->occurencies;
int val_2 = bb->occurencies;
if(val_1 == val_2){
return 0;
}else if(val_1 > val_2){
return 1;
}else{
return -1;
}
}
Sorry for the formatting, i am new to asking questions here.
I hope you can help thankyou.
Array code :
/*DynArray is a dynamically resizing array that is used to hold values and retain size data throughout*/
typedef struct{
int number_of_values;
int capacity;
HashItem **items;
}DynArray;
/*Method to create a new dynamic array and return it */
DynArray* array_new(int file_size){
DynArray *array = malloc(sizeof(DynArray));
array->number_of_values = 0;
array->capacity = file_size / 10;
printf("capacity is %d " , array->capacity);
array->items = malloc(sizeof(HashItem*)* array->capacity);
}
/*Method used to increase the size of the array and reallocate memory*/
void array_increase_if_full(DynArray *array){
if (array->number_of_values >= array->capacity){
array->capacity *= 1.25;
array->items = realloc(array->items, sizeof(HashItem)*array->capacity);
}
}
/*Method to add a string to the dynamic array specified */
void array_append(DynArray *array, HashItem *item){
array_increase_if_full(array);
array->items[array->number_of_values] = item;
//printf("item %s added \n at position %d ", array->items[array->number_of_values]->word, array->number_of_values);
array->number_of_values++;
}
/*Method used to get value at specified position for given array*/
HashItem *array_get(DynArray *array, int position){
if(position >= array->number_of_values || position <0){
printf("Index specified out of range");
exit(1);
}
//printf("item %s at position %d retrieved", array->items[position]->word, position);
return array->items[position];
}
HashItem **array_getarray(DynArray *array){
HashItem **toreturn[array->number_of_values];
int i;
for(i = 0; i < array->number_of_values; i++){
toreturn[i] = array_get(array, i);
}
return toreturn;
}
Printing the array from the main gives the correct unsorted values of word:occurences
Edit:
Thanks to everyone that took their time to help, it is now in a working state with Michaels suggestion, i no longer use the array_getarray() method and instead use:
int n = array->number_of_values;
int i;
HashItem **standard_array = malloc(n*sizeof(HashItem*));
for(i = 0; i < n; i++){
standard_array[i] = array_get(array, i);
printf("%s : %d \n" , standard_array[i]->word, standard_array[i]->occurences);
}
You structure declaration:
typedef struct {
char *word;
int occurences;
} HashItem;
declares a typedef name for an anonymous struct. There is a HashItem type that's a structure, but there is no struct HashItem type.
So when your compare_func() has the following declarations:
const struct HashItem* aa = (HashItem*)a;
const struct HashItem* bb = (HashItem*)b;
those struct HashItem* variables are pointers to a forward declared struct HashItem that has nothign to do with the HashItem strucuture above.
Just change those variable declarations to:
const HashItem* aa = (HashItem*)a;
const HashItem* bb = (HashItem*)b;
and/or change the declaration of the structure to:
typedef struct HashItem {
char *word;
int occurences;
} HashItem;
However, there's another issue (as mentioned in other answers): you are apparently sorting an array of pointers to HashItem objects, but your compare_function() is being written as if you're sorting an array of the objects (not pointers).
To address this:
int compare_func(const void *a, const void *b)
{
// get HashItem*'s from the HashItem**'s
const HashItem* aa = *((HashItem**)a);
const HashItem* bb = *((HashItem**)b);
int val_1 = aa->occurencies;
int val_2 = bb->occurencies;
if (val_1 == val_2) {
return 0;
} else if (val_1 > val_2) {
return 1;
} else {
return -1;
}
}
Finally (for now anyway), this function is returning the address to a local array, so the data it points to is no longer valid:
HashItem **array_getarray(DynArray *array){
HashItem **toreturn[array->number_of_values];
int i;
for(i = 0; i < array->number_of_values; i++){
toreturn[i] = array_get(array, i);
}
return toreturn;
}
I think you'll need to allocate the array you're retuning using malloc() or calloc() or something. But what I really think you need to do is step back and create some drawing of your data structures and think about the lifetime of the various objects contained in them and how those lifetimes can be tracked an managed so that you don't have leaks, double frees, or pointer dereferences to no longer valid objects.
Change qsort(standard_array, n, sizeof(HashItem), compare_func); to
qsort(standard_array, n, sizeof(HashItem*), compare_func);
In function void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
the third parameter size_t size stands for:
Size in bytes of each element in the array.
It now looks to me like your problems are all springing from the first definition.
/*DynArray is a dynamically resizing array that is used to hold values and retain size data throughout*/
typedef struct{
int number_of_values;
int capacity;
HashItem **items;
}DynArray;
I see no reason for items to be a double-pointer. The comment says it should contain values, but a double-pointer pointing to an array would contain pointers, not the ultimate values. I think this initial misstep is causing you to trip everywhere else. Change it to
...
HashItem *items;
...
and the rest should flow more naturally.

Sorting Array of Struct Pointers

I am trying to sort array of structs using qsort() but frustratingly, it's not working. I have read the manpage for qsort() and I think I have the comparator function that syntactically looks okay, but when I print the "sorted" array after calling qsort(), nothing is sorted in my array.
The code:
#include <stdlib.h>
#include <stdio.h>
#define ARRAY_SZ 5
typedef struct SingleChar
{
unsigned char Character;
unsigned int Weight;
} *SingleCharPtr;
int CompareWeights(const void *a, const void *b)
{
const SingleCharPtr p1 = (SingleCharPtr)a;
const SingleCharPtr p2 = (SingleCharPtr)b;
// printf("Weight1: %u\tWeight2: %u\n", p1->Weight, p2->Weight);
// return (p1->Weight - p2->Weight);
if (p1->Weight < p2->Weight)
return -1;
else if (p1->Weight > p2->Weight)
return 1;
else
return 0;
}
SingleCharPtr MakeChar(unsigned char c, unsigned int w)
{
SingleCharPtr scptr = malloc(sizeof(struct SingleChar));
if (!scptr)
{
fprintf(stderr, "[Error] Out of memory\n");
exit(1);
}
scptr->Character = c;
scptr->Weight = w;
return scptr;
}
int main(void)
{
SingleCharPtr *chars = malloc(ARRAY_SZ * sizeof(SingleCharPtr));
chars[0] = MakeChar('B', 3);
chars[1] = MakeChar('E', 7);
chars[2] = MakeChar('A', 4);
chars[3] = MakeChar('D', 6);
chars[4] = MakeChar('C', 2);
qsort(chars, ARRAY_SZ, sizeof(SingleCharPtr), &CompareWeights);
int i;
for (i = 0; i < ARRAY_SZ; i++)
{
printf("Character: %c\tWeight: %u\n", chars[i]->Character, chars[i]->Weight);
free(chars[i]);
}
free(chars);
return 0;
}
Also, in the comparator function (CompareWeights()), I found out that when I print the weight of the structs pointed by SingleCharPtr, I get 0s for all of them.
Any pointer to right direction would be highly appreciated.
The problem: qsort() passes in pointers to the elements to be compared to the comparator function, and not the elements themselves. So, the arguments to your CompareWeights() function are actually const SingleCharPtr *, disguised as const void *. What you should do in that function is:
const SingleCharPtr p1 = *(const SingleCharPtr *)a;
etc.
Sidenotes:
I. If your assumption had been valid, then you wouldn't have needed the cast:
const SingleCharPtr p1 = a;
is preferred over
const SingleCharPtr p1 = (SingleCharPtr)a;
because of this.
II. The comparison function need not return -1, 0 or 1. It should return an integer less than 0, 0 or greater than 0. Thus, all the huge if in CompareWeight() is completely superfluous, write
return p1->Weight - p2->Weight;
instead.
III. SingleCharPtr *chars = malloc(ARRAY_SZ * sizeof(SingleCharPtr)); - Why? You only use the chars array locally in the main() function, you don't need dynamic allocation for that. Why not write
SingleCharPtr chars[ARRAY_SZ];
instead?
If you see the example in e.g. this manual page, you will see that the when qsort is passed an array of pointer (just like you have) then the arguments to the sorting function are actually pointers to pointers. This is because qsort passes pointers to the elements, not the elements themselves.
To accomodate for that, change accordingly:
int CompareWeights(const void *a, const void *b)
{
const SingleCharPtr p1 = *(SingleCharPtr*)a;
const SingleCharPtr p2 = *(SingleCharPtr*)b;
return (p1->Weight - p2->Weight);
}

function to compare ints when using qsort on array of structure pointers in c

There are lots of questions on stackoverflow regarding how to sort an array of structure pointers. I looked through them all, to no avail. I want to sort an array of pointers to an array of structures. I first allocate storage for the pointer array, then for the structures themselves. All that seems fine, but I can't get them sorted. I'm sure the problem is in the compare function. I've copied a few of them from stackoverflow, and they are listed below. But none of them work...
typedef struct s_stream{
int amc;
char *name;
} dataStream;
void abc(void)
{
int count = 100;
dataStream *_UniqueStreamBuild = calloc(count, sizeof(dataStream ));
dataStream **UniqueStreamBuild = calloc(count, sizeof(dataStream *));
for ( int i = 0; i < count; ++i) UniqueStreamBuild[i] = _UniqueStreamBuild + i;
//**Edit: ******** **
// here I call a cascade of functions that assign values to amc; those
// functions are correct: they produce an unsorted array of amc values;
// the output I am getting is an array of structures seemingly in random order.
qsort(UniqueStreamBuild, count, sizeof(dataStream *), compare);
}
int compare (const void * a, const void * b)
{
const dataStream *x = a;
const dataStream *y = b;
if (x->amc > x->amc)
return(1);
if (x->amc < x->amc)
return(-1);
return(0);
}
int compare( const void *a, const void *b )
{
dataStream *m1 = *(dataStream **)a;
dataStream *m2 = *(dataStream **)b;
if (m1->amc > m2->amc)
return(1);
if (m1->amc < m2->amc)
return(-1);
return(0);
}
Your second possible compare() function should work unless there's some difference I didn't notice between it and this version just below. When sorting an array of pointers, the comparison function is passed two pointers to a dataStream *, hence the comparator should be very similar to this:
int compare (const void *a, const void *b)
{
const dataStream *x = *(const dataStream **)a;
const dataStream *y = *(const dataStream **)b;
if (x->amc > y->amc)
return(1);
else if (x->amc < y->amc)
return(-1);
else
return(0);
}
Also, as originally written, one of your functions always returns 0 because x->amc == x->amc (you dereference x twice, instead of x and y).
Your test code does not fully initialize the data structures - it uses calloc() so the strings and pointers in the structures are all zeroed, so sorting doesn't do much.
This code works for me...how about you?
#include <stdio.h>
#include <stdlib.h>
typedef struct s_stream
{
int amc;
char *name;
} dataStream;
static int compare(const void *a, const void *b)
{
const dataStream *x = *(const dataStream **)a;
const dataStream *y = *(const dataStream **)b;
if (x->amc > y->amc)
return(1);
else if (x->amc < y->amc)
return(-1);
else
return(0);
}
static void dump(FILE *fp, const char *tag, dataStream * const * const data, int num)
{
const char *pad = "";
fprintf(fp, "Stream Dump (%s): (%d items)\n", tag, num);
for (int i = 0; i < num; i++)
{
fprintf(fp, "%s%d", pad, data[i]->amc);
if (i % 10 == 9)
{
putc('\n', fp);
pad = "";
}
else
pad = ", ";
}
putc('\n', fp);
}
static void abc(void)
{
int count = 100;
dataStream *_UniqueStreamBuild = calloc(count, sizeof(dataStream ));
dataStream **UniqueStreamBuild = calloc(count, sizeof(dataStream *));
for ( int i = 0; i < count; ++i)
{
UniqueStreamBuild[i] = _UniqueStreamBuild + i;
UniqueStreamBuild[i]->amc = (7 * i + 3) % count + 1;
}
dump(stdout, "Before", UniqueStreamBuild, count);
qsort(UniqueStreamBuild, count, sizeof(dataStream *), compare);
dump(stdout, "After", UniqueStreamBuild, count);
free(_UniqueStreamBuild);
free(UniqueStreamBuild);
}
int main(void)
{
abc();
return 0;
}

Returning a 2D char array in C

I messed around with this enough but I really don't get it.
Here is what I want to do: Take a 2D char array as an input in a function, change the values in it and then return another 2D char array.
That's it. Quite simple idea, but ideas do not get to work easily in C.
Any idea to get me started in its simplest form is appreciated. Thanks.
C will not return an array from a function.
You can do several things that might be close enough:
You can package your array in struct and return that. C will return structs from functions just fine. The downside is this can be a lot of memory copying back and forth:
struct arr {
int arr[50][50];
}
struct arr function(struct arr a) {
struct arr result;
/* operate on a.arr[i][j]
storing into result.arr[i][j] */
return result;
}
You can return a pointer to your array. This pointer must point to memory you allocate with malloc(3) for the array. (Or another memory allocation primitive that doesn't allocate memory from the stack.)
int **function(int param[][50]) {
int arr[][50] = malloc(50 * 50 * sizeof int);
/* store into arr[i][j] */
return arr;
}
You can operate on the array pointer passed into your function and modify the input array in place.
void function(int param[][50]) {
/* operate on param[i][j] directly -- destroys input */
}
You can use a parameter as an "output variable" and use that to "return" the new array. This is best if you want the caller to allocate memory or if you want to indicate success or failure:
int output[][50];
int function(int param[][50], int &output[][50]) {
output = malloc(50 * 50 * sizeof int);
/* write into output[i][j] */
return success_or_failure;
}
Or, for the caller to allocate:
int output[50][50];
void function(int param[][50], int output[][50]) {
/* write into output[i][j] */
}
You cannot return an array from a function.
You have several options:
wrap arrays inside structs
struct wraparray {
int array[42][42];
};
struct wraparray foobar(void) {
struct wraparray ret = {0};
return ret;
}
pass the destination array, as a pointer to its first element (and its size), to the function; and change that array
int foobar(int *dst, size_t rows, size_t cols, const int *src) {
size_t len = rows * cols;
while (len--) {
*dst++ = 42 + *src++;
}
return 0; /* ok */
}
// example usage
int x[42][42];
int y[42][42];
foobar(x[0], 42, 42, y[0]);
change the original array
int foobar(int *arr, size_t rows, size_t cols) {
size_t len = rows * cols;
while (len--) *arr++ = 0;
return 0; /* ok */
}
char **foo(const char * const * bar, size_t const *bar_len, size_t len0) {
size_t i;
char** arr = malloc(sizeof(char *) * len0);
for (i = 0; i < len0; ++i) {
arr[i] = malloc(bar_len[i]);
memcpy(arr[i], bar[i], bar_len[i]);
}
/* do something with arr */
return arr;
}
Somewhere else in your code:
char **pp;
size_t *pl;
size_t ppl;
/* Assume pp, pl are valid */
char **pq = foo(pp, pl, ppl);
/* Do something with pq */
/* ... */
/* Cleanup pq */
{
size_t i;
for (i = 0; i < ppl; ++i)
free(pq[i]);
free(pq);
}
Because you're passing by-pointer instead of by-value and you want to write to the input array, you have to make a copy of it.
Here's another example. Tested and works.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void test(char**,unsigned int,unsigned int);
const unsigned int sz_fld = 50 + 1;
const unsigned int sz_ffld = 10;
int main(void) {
char fld[sz_ffld][sz_fld];
for (unsigned char i=0;i<sz_ffld;++i) {
strcpy(fld[i],"");
}
strcpy(fld[0],"one");
strcpy(fld[1],"two");
strcpy(fld[2],"three");
char** pfld = malloc(sz_ffld*sizeof(char*));
for (unsigned int i=0;i<sz_ffld;++i) {
*(pfld+i) = &fld[i][0];
}
test(pfld,sz_ffld,sz_fld);
printf("%s\n",fld[0]);
printf("%s\n",fld[1]);
printf("%s\n",fld[2]);
free(pfld);
return(0);
}
void test(char** fld,unsigned int m,unsigned int n) {
strcpy(*(fld+0),"eleven");
strcpy(*(fld+1),"twelve");
return;
}
Note the following:
For compiling, I am using gcc with the C99 option.
I defined the function to include the two sizes information, but I wrote very basic code and am not actually using the information at all, just the strcpy(), so this certainly is not security-safe code in any way (even though I'm showing the "m" and "n" for such facility). It merely shows a technique for making a static 2D char array, and working with it in a function through the intermediate of an array of pointers to the "strings" of the array.
When you pass a 2D array to a function as a parameter, you need to explicitly tell it the size of the arrays second dimension
void MyFunction(array2d[][20]) { ... }
The following will do what you want. it will print "One" and "Ten". Also note that it is typed to the exact array dimensions of 10 and 8.
char my_array[10][8] =
{
{"One"},
{"Two"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"Nine"},
{"Ten"},
};
void foo ( char (**ret)[10][8] )
{
*ret = my_array;
}
void main()
{
char (*ret)[10][8];
foo(&ret);
printf("%s\r\n", (*ret)[0] )
printf("%s\r\n", (*ret)[9] )
}
The original question was about RETURNING the array, so I'm updating this to show returning a value. You can't "return an array" directly, but you CAN make a typedef of an array and return that...
char my_array[10][8];
typedef char ReturnArray[8];
ReturnArray* foo()
{
return my_array;
}

Resources