I'm writing a program to perform shellsort on an array of numbers. I first have to generate the sequence of numbers that shellsort will be performed with. This function is to generate numbers of the form 2^p*3^q that are less than the length of the array to be sorted. Then I sort the sequence array that I just generated. Here's my implementation of this:
long * Generate_2p3q_Seq(int length, int *seq_size) {
int ind = 0;
long * arr[1000];
int product;
int power = 1;
while (power < length) {
product = power;
while (product < length) {
arr[ind] = product;
product *= 3;
ind++;
}
power *= 2;
}
int i, j, k;
for (i = 0; i < ind; ++i) {
for (j = i + 1; j < ind; ++j)
{
if (arr[i] > arr[j])
{
k = arr[i];
arr[i] = arr[j];
arr[j] = k;
}
}
}
*seq_size = ind;
for (int count = 0; count < ind; count++) {
printf("arr[%d] = %li\n", count, arr[count]);
}
return arr;
}
The code is meant to return a long * array and set seq_size to the length of the sequence array. For example, if I'm given an array of 16 integers to be sorted, the sequence array generated here should be 8 integers (1, 2, 3, 4, 6, 9, 8, 12) and seq_size should equal 8. I believe my understanding of pointers is wrong because my terminal output looks like this:
sequence.c: In function ‘Generate_2p3q_Seq’:
sequence.c:14:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
arr[ind] = product;
^
sequence.c:26:11: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
k = arr[i];
^
sequence.c:28:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
arr[j] = k;
^
sequence.c:34:25: warning: format ‘%li’ expects argument of type ‘long int’, but argument 3 has type ‘long int *’ [-Wformat=]
printf("arr[%d] = %li\n", count, arr[count]);
~~^ ~~~~~~~~~~
%ln
sequence.c:36:10: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
return arr;
^~~
sequence.c:36:10: warning: function returns address of local variable [-Wreturn-local-addr]
However, I'm not sure how to change this to make it work. I call this function with:
long * sequence = Generate_2p3q_Seq(size, &seq_size);
Please let me know if there's any information I've left out, I really appreciate any help.
There are two main issues here. First, you declare arr
as long *arr[1000]
, which means it is an array of pointer to long
, not an array of long
. That is why you're getting about conversions between pointers and integers.
The proper way to define an array of long
is:
long arr[1000];
But this then leads to the second problem, namely that you are returning a pointer to a local variable. When the function returns its local variables go out of scope, so the returned pointer no longer points to valid memory.
To fix this, declare arr
as a pointer and use malloc
to dynamically allocate memory for it:
long *arr = malloc((product * power) * sizeof *arr);
if (!arr) {
perror("malloc failed");
exit(1);
}
Then you can return the value of arr
, which points to dynamically allocated memory.