Expanding Static Arrays in C - c

Is it possible to extend a static array in C?
I tried creating a function which allocates a new dynamic array, copies contents to it and returns it's pointer; but It didn't work correctly, I'm getting debug error everytime.
I need to do something like this;
int a1[5] = { 1,2,5,4,1 };
extend(a1); //or a1* = extend(a1);
.
.
.
a1[9] = 2;
My extend function so far;
int extend(int x[], int oldSize, int newSize) {
int *extendedX = (int*)calloc(newSize, sizeof(int));
int i = 0;
for (; i < oldSize;i++) {
extendedX[i] = x[i];
}
for (; i < newSize; i++) {
extendedX[i] = 0;
}
return *extendedX;
}

extend(a1); //or a1* = extend(a1);
Your function extend needs to return int * instead of just int.
int* extend(int x[], int oldSize, int newSize);
Also, you need to create a new pointer a2 to be assigned to the return value of extend function:
int *a2 = extend( a1, oldSize, newSize );

You can't extend static array.
you can do it like this:
#include <stdio.h>
int *extends(int ar[],int oldsz,int newsz){
int *newAr = malloc(newsz*sizeof(int));
for(int i = 0; i < oldsz;i++){
newAr[i] = ar[i];
}
return newAr;
}
int main(void) {
int i,a[5] = { 1, 2, 3, 4, 5};
int *a1 = extends(a,5,10);
a1[5] = 6;
a1[6] = 7;
a1[7] = 8;
a1[8] = 9;
a1[9] = 10;
a1[10] = 11;
a1[11] = 12;
for(i = 0; i < 12; i++)printf("%d ",a1[i]);
return 0;
}

You can't extend a static array, it's size is determined at compile time.
However, you could declare a1 as a pointer, and use a static initializer to set the initial value,
int *a1 = (int[]){ 1, 2, 5, 4, 1};
then later assign the result of the extend function (which should return an int * like #artm suggested).

Related

How to access 2 dimensional Array Pointer in a typedef-struct over a function in c

I have Problems with accessing the 2D Array in a typedef from a other function over a pointer, even if i allocate the array in heap!
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int a;
int b;
int **data;
} Image;
Image *createImage(int a, int b) {
Image createImage;
createImage.data = malloc(a * sizeof(int *));
for (int i = 0; i < a; i++) {
createImage.data[i] = malloc(b * sizeof(int));
}
Image *imagePointer = malloc(sizeof(Image));
imagePointer = &createImage;
return imagePointer;
}
int main () {
int a = 70;
int b = 90;
Image *imagePointer = createImage(a, b);
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
imagePointer->data[i][j] = i + j;
}
}
}
I get an error at load Image because i have done something wrong with accessing the allocated storage. What should i change?
Jonathan
Instead of returning a pointer to Image return the local variable itself and it works. Also variable name and function name should not be same createImage it creates confusion sometimes.
#include <stdlib.h>
typedef struct {
int a;
int b;
int **data;
} Image;
Image createImage(int a, int b) {
Image ci;
ci.data = malloc(a * sizeof(int *));
for (int i = 0; i < a; i++) {
ci.data[i] = malloc(b * sizeof(int));
}
return ci;
}
int loadImage () {
int a = 70;
int b = 90;
Image imagePointer = createImage(a, b);
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
imagePointer.data[i][j] = i + j;
}
}
}
int main(int argc, char const *argv[])
{
loadImage();
return 0;
}
It is not 2D array only an array of pointers.
Use size_t for sizes
Use objects not types in sizeof
Always check the result of malloc
I would use flexible array member and array pointers to remove one level of indirection and ease allocation and deallocation (only one malloc/free needed)
typedef struct {
size_t a;
size_t b;
unsigned data[];
} Image;
Image *createImage(const size_t a, const size_t b)
{
Image *imagePointer;
imagePointer = malloc(sizeof(*imagePointer) + a * b * sizeof(imagePointer -> data[0]));
if(imagePointer)
{
imagePointer -> a = a;
imagePointer -> b = b;
}
return imagePointer;
}
int main (void)
{
const size_t a = 70;
const size_t b = 90;
Image *imagePointer = createImage(a, b);
if(imagePointer)
{
unsigned (*image)[imagePointer -> b] = (unsigned (*)[imagePointer -> b])imagePointer -> data;
for (size_t i = 0; i < a; i++)
{
for (size_t j = 0; j < b; j++)
{
image[i][j] = i + j;
}
}
}
}

Sum of two arrays using pointers in C

I am trying to create a program in C that calculates the sum of two int arrays using pointers.
Here is an example of what I want to do:
int a[] = {1,2,3,4}
int b[] = {1,2,3,4,5,6}
int c[] = sumArrays(a,b,4,6)
Output : c = {2,4,6,8,5,6}
The problem is my output is different, it shows:
Output : c = {2,4,6,8}
Any idea what did I do wrong and how to correct it ?
Here is my code :
#include <stdio.h>
#include <stdlib.h>
int* sumArrays(int *arr1, int *arr2, int dim1,int dim2)
{
int *ret = NULL;
if(dim1<dim2) ret = (int*) malloc(dim2*sizeof(int));
else ret = (int*) malloc(dim1*sizeof(int));
if(ret)
{
if(dim1<dim2) {
int i = 0;
for (i = 0;i < dim1;i++) {
ret[i] = arr1[i] + arr2[i];
}
for (i = dim1; i < dim2;i++) {
ret[i]=arr2[i];
}
} else {
int i = 0;
for (i = 0;i < dim2;i++) {
ret[i] = arr1[i] + arr2[i];
}
for (i = dim2; i < dim1;i++) {
ret[i]=arr1[i];
}
}
}
return ret;
}
int main()
{
int *a[] = {1,2,3,4};
int *b[] = {1,2,3,4,5,6};
int *c = sumArrays(a,b,4,6);
printf("c = ");
int i;
for (i = 0; i < sizeof(c); i++) {
printf("%d,",c[i]);
}
}
Sizeof c will always return 4 for 32-bit system and 8 for 64-bit, because c is a pointer to int.
So to print the result array you should write:
for (i = 0; i < 6; i++) {
You have problem about using pointers.
int *a[] = {1,2,3,4}; // a is an array of pointers to integers.
int *b[] = {1,2,3,4,5,6}; // b is an array of pointers to integers.
By doing this, you are declaring array of pointers to integers. So, it most likely causes compiler warning or error depending on your compile settings like, initialization makes pointer from integer without a cast. When you are passing the actual arguments to formal parameters, it causes same warning as well. Your main should be like this,
int main()
{
int a[] = {1,2,3,4};
int b[] = {1,2,3,4,5,6};
int sizeA = sizeof(a) / sizeof(*a);
int sizeB = sizeof(b) / sizeof(*b);
int *c = sumArrays(a,b,sizeA,sizeB);
printf("c = ");
int i;
for (i = 0; i < (sizeA < sizeB ? sizeB : sizeA); i++) {
printf("%d,",c[i]);
}
}

C - Sort float array while keeping track of indices

I have an array of 3 floating point values:
float norms[3];
norms[0] = 0.4;
norms[1] = 3.2;
norms[2] = 1.7;
I want to sort this array in descending order while keeping track of the original indexes of the values in the array.
In other words, given the array norms[] = {0.4, 3.2, 1.7} with corresponding indices {0, 1, 2}, I basically want to obtain an array of corresponding ints that reflects the original positions of the float values in norms[] following a descending sort. In this case it would be {1, 2, 0}.
What is the best/cleanest way to achieve this?
Use a structure to store the value as well as index and then sort according to value.
struct str
{
float value;
int index;
};
int cmp(const void *a, const void *b)
{
struct str *a1 = (struct str *)a;
struct str *a2 = (struct str *)b;
if ((*a1).value > (*a2).value)
return -1;
else if ((*a1).value < (*a2).value)
return 1;
else
return 0;
}
int main()
{
float arr[3] = {0.4, 3.12, 1.7};
struct str objects[3];
for (int i = 0; i < 3; i++)
{
objects[i].value = arr[i];
objects[i].index = i;
}
//sort objects array according to value maybe using qsort
qsort(objects, 3, sizeof(objects[0]), cmp);
for (int i = 0; i < 3; i++)
printf("%d ", objects[i].index); //will give 1 2 0
// your code goes here
return 0;
}
Just use any sorting algorithm 'aliasing' the original array access. Example with bubblesort
int len = 3;
bool switched = false;
float myFloatArr[3];
int myFloatIndex[3] = {0, 1, 2};
do
{
switched = false;
for(i = 1; i < len; i++)
{
if(myFloatArr[myFloatIndex[i - 1]] < myFloatArr[myFloatIndex[i]])
{
int temp = myFloatIndex[i];
myFloatIndex[i] = myFloatIndex[i - 1];
myFloatIndex[i - 1] = temp;
switched = true;
}
}
}
while(switched);
The cleanest way i can think of is to create a structure which contains both float and index.
typedef struct str {
float val;
int index;
} str;
then create an array of this structure and sort it according to val.

Dynamically create and initialize an array of pointers to struct in C

Here is an example code of what I'm trying to achieve
typedef struct
{
int x_pos, y_pos;
} A;
typedef struct
{
A **arrayAp;
} B;
int main(void) {
B B;
int n = 10;
A *array[n];
B.arrayAp = array;
for (int i = 0; i < 10; i++)
{
B.arrayAp[i] = malloc(sizeof(A));
B.arrayAp[i]->x_pos = i;
B.arrayAp[i]->y_pos = i + 1;
}
printf("%d",B.arrayAp[0]->x_pos);
}
It works as I want it to work. I can access elements of "array" using "arrayAp" pointer. But when I try to move some of this code to function for example:
A * makeAnArray()
{
int n = 10;
A *array[n];
return &array;
}
and then assign value that it returns to "arrayAp"
B.arrayAp = makeAnArray();
Now I can't access first element of the array. Program just crash.
printf("%d",B.arrayAp[0]->x_pos);
But starting from second element everything works the same.
But the bigger problem I get when I try to move to function this code:
void initializeAnArray(B *B)
{
for (int i = 0; i < 10; i++)
{
B->arrayAp[i] = malloc(sizeof(A));
B->arrayAp[i]->x_pos = i;
B->arrayAp[i]->y_pos = i + 1;
}
}
Seems like it has no effect. When i'm trying to access array member through "arrayAp" pointer i'm getting some "random" values from memory.
typedef struct
{
int x_pos, y_pos;
} A;
typedef struct
{
A **arrayAp;
} B;
A * makeAnArray()
{
int n = 10;
A *array[n];
return &array;
}
void initializeAnArray(B *B)
{
for (int i = 0; i < 10; i++)
{
B->arrayAp[i] = malloc(sizeof(A));
B->arrayAp[i]->x_pos = i;
B->arrayAp[i]->y_pos = i + 1;
}
}
int main(void) {
B B;
B.arrayAp = makeAnArray();
initializeAnArray(&B);
printf("%d",B.arrayAp[1]->x_pos);
}
Sorry for my poor English.
Your function should be:
A * makeAnArray()
{
int n = 10;
//A *array[n]; --> This is local to this function so won't work
A *array = malloc(sizeof(A)*n); //--> Dynamic allocation
return array;
}
A * makeAnArray()
{
int n = 10;
A *array[n];
return &array;
}
You are returning a local pointer which dies after the function ends and causes UB.
Moreover return type of your function should be A** and you should allocate memory with *alloc and return to ensure every instance is different and is alive after the function call.
Possible fix
A * makeAnArray()
{
int n = 10;
A *array = malloc(n * sizeof(A));
return array;
}
The part
A * makeAnArray()
{
int n = 10;
A *array[n];
return &array;
}
is not going to work. The array array might be allocated on the stack, it cannot be accessed via the return value after termination of makeAnArray; the result is undefined behaviour.

Return a 2d array from a function

I am a newbie to C.
I am trying to return a 2d array from a function.
It is something like this
int *MakeGridOfCounts(int Grid[][6])
{
int cGrid[6][6] = {{0, }, {0, }, {0, }, {0, }, {0, }, {0, }};
int (*p)[6] = cGrid;
return (int*)p;
}
I know this causes an error, need help. thanks
The C language has a basic flaw: it is impossible to return arrays from functions.
There are many workarounds for this; i'll describe three.
Replace by a pointer to an array
Return a pointer instead of an array itself. This leads to another problem in C: when a function returns a pointer to something, it should usually allocate the something dynamically. You should not forget to deallocate this later (when the array is not needed anymore).
typedef int (*pointer_to_array)[6][6];
pointer_to_array workaround1()
{
pointer_to_array result = malloc(sizeof(*result));
(*result)[0][0] = 0;
(*result)[1][0] = 0;
(*result)[2][0] = 0;
(*result)[3][0] = 0;
(*result)[4][0] = 0;
(*result)[5][0] = 0;
return result;
}
Replace by a pointer to int
A 2-D array appears just as a sequence of numbers in memory, so you can replace it by a pointer to first element. You clearly stated that you want to return an array, but your example code returns a pointer to int, so maybe you can change the rest of your code accordingly.
int *workaround2()
{
int temp[6][6] = {{0}}; // initializes a temporary array to zeros
int *result = malloc(sizeof(int) * 6 * 6); // allocates a one-dimensional array
memcpy(result, temp, sizeof(int) * 6 * 6); // copies stuff
return result; // cannot return an array but can return a pointer!
}
Wrap with a structure
It sounds silly, but functions can return structures even though they cannot return arrays! Even if the returned structure contains an array.
struct array_inside
{
int array[6][6];
};
struct array_inside workaround3()
{
struct array_inside result = {{{0}}};
return result;
}
It sounds like you want a function returning pointer to array[6] of int:
int (*makeGrid())[6]
{
return calloc(6*6,sizeof(int)); //zeros the memory as in your example.
}
You would call and use it like so:
int (*arr)[6] = makeGrid();
arr[4][3] = 3; //etc...
Try this out, compiles fine with GCC on my mac..
typedef struct _intGrid_t{
int **data;
int width;
int height;
} *IntGrid;
IntGrid makeGridWithSize(int width, int height);
IntGrid makeGridWithSize(int width, int height)
{
IntGrid grid = malloc(sizeof(struct _intGrid_t));
int **data = (int **) malloc(sizeof(int *) * width);
for (int i = 0; i < width; i++) {
data[i] = malloc(sizeof(int) * height);
memset(data[i], 0, sizeof(int) * height);
}
grid->data = data;
grid->width = width;
grid->height = height;
return grid;
}
void printGrid(IntGrid grid);
void printGrid(IntGrid grid)
{
printf(" { \n");
for (int i =0; i < grid->width; i++) {
printf(" { ");
for (int j = 0; j < grid->height; j++) {
printf("%i", grid->data[i][j]);
if (j != grid->height - 1)
{
printf(", ");
}
}
printf(" } \n");
}
printf(" } \n");
}
void freeGrid(IntGrid grid);
void freeGrid(IntGrid grid)
{
for (int i = 0; i < grid->width; i++) {
free(grid->data[i]);
}
free(grid->data);
free(grid);
}
int main (int argc, const char * argv[])
{
srand((int) time(NULL));
IntGrid grid = makeGridWithSize(10, 10);
for (int i = 0; i < grid->width; i++) {
for (int j = 0; j < grid->height; j++) {
grid->data[i][j] = rand() % 10;
}
}
printGrid(grid);
freeGrid(grid);
return 0;
}

Resources