Is there a best practice for allocating memory in C? - c

I've been trying to make a function that appends matrix B onto Matrix A by making a new combined matrix. The first function I created passes a pointer (that was declared in main()) to the function which then works up the pointer to add values. This worked. However, I am also trying a different method by using malloc() within the function to define a pointer so that the function is more portable and dyanmic. However, when I try to print the final values in the final matrix I am getting undefined behavior.
Here is the included function from the created header file.
#include <stdio.h>
#include <stdlib.h>
int *fAddArrays(int *A, int *B, int a, int b)
{
int *O;
O = (int *) malloc((a+b) * sizeof(int));
int c;
int d;
for (c = 0; c < a; c++)
{
*O = *A;
A++;
O++;
}
for (d = 0; d < b; d++)
{
*O = *B;
B++;
O++;
}
return O;
}
Here is the use of the function in main()
#include <stdio.h>
#include <unistd.h>
#include "CustomArray.h"
#include <stdlib.h>
int main(void)
{
int A[5] = {1,2,3,4,5};
int B[7] = {6,7,8,9,10,11,12};
int a = 5;
int b = 7;
int c = a + b;
int x = 0;
int NewArray[c], *ArrayPtr;
ArrayPtr = fAddArrays(A,B,a,b);
for( x = 0; x < c; x++)
{
*(NewArray + x) = *ArrayPtr;
printf("Value of NewArray[%d] = %d\n", x, *ArrayPtr);
sleep(1);
ArrayPtr++;
}
return 0;
}

Your problem is that you increment O and then return it.
You need to save away the original value and increment a copy.
int *fAddArrays(int *A, int *B, int a, int b) {
int * original = (int *) malloc((a+b) * sizeof(int));
int * p = original;
for (int c = 0; c < a; c++) {
*p = *A;
A++;
p++;
}
for (int d = 0; d < b; d++) {
*p = *B;
B++;
p++;
}
return original;
}

Related

How to access the attributes of a struct in a 2D array

I have a simple program that makes a 2d array of a struct. I want to know how to manipulate the struct's attributes. This is my attempt; i keep getting Segmentation fault, the problem happens in the fillarr method;
My problem is that i don't quite understand how to manipulate the data once it is in a 2D array. I understand that arrays are pointers, my assumption at first was that i could do something like
arr[h][w]->one = 'b';
Which i now know is obviously wrong because the compiler really doesn't like it.
Now, when i try
arr[h][w].one = 'a'
The compiler doesn't complain about that syntax, but this is where my segmentation fault triggers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char one;
char two;
};
typedef struct node node;
node** makeArr(int h, int w) {
printf("Making arr\n");
node** output = (node**)malloc(sizeof(node*) * h);
for (int i = 0; i < h; i++) {
output[i] = (node*)malloc(sizeof(node) * w);
}
return output;
}
void killarr(node **arr, int h, int w) {
printf("Killing arr\n");
for (int i = 0; i < h; i++) {
free(arr[i]);
}
free(arr);
}
void fillarr(node **arr, int h, int w) {
printf("Filling arr\n");
char x = 'a';
for (int i = 0 ; i < h; i++) {
for(int m = 0; m < w; m++){
arr[h][w].one = x++; // <- here exactly
arr[h][w].two = x++; // <- here too
}
}
}
int main(int argc, char *argv[]) {
int h = 10;
int w = 10;
node **arr = makeArr(h, w);
fillarr(arr, h, w);
killarr(arr, h, w);
}
Each time through the inner loop you're accessing arr[h][w]. But since h and w are the array bounds, you're accessing out of bounds, leading to undefined behavior.
You likely meant:
arr[i][m].one = x++;
arr[i][m].two = x++;

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;
}
}
}
}

How can I access an array created in another function in main without returning it?

First post on StackOverflow. I'm supposed to create a function:
int sumsort(int *a, int *b, int *c)
This function should arrange the 3 values in the memory locations pointed to
by a, b, and c in ascending order and also return the sum of the contents of
the memory locations a, b, and c.
Here's my function:
int sumsort(int *a, int *b, int *c) {
int sum = *a + *b + *c;
int sorted[] = {*a, *b, *c};
for (int i = 0; i <= 2; i++) {
if (sorted[0] > sorted[1])
{
int temp = sorted[1];
sorted[1] = sorted[0];
sorted[0] = temp;
} // end if
if (sorted[1] > sorted[2])
{
int temp2 = sorted[2];
sorted[2] = sorted[1];
sorted[1] = temp2;
} // end if
} // end for
return sum;
} // end sumsort function
How can I access the sorted[] array in main? I need to print the 3 variables in ascending order but don't really see how I can do that since the sumsort function has to return the sum and the actual sorting has to happen in the sumsort function too.
I tried creating a new array variable in main and assigning it sorted[] after I call the sumsort function, but that doesn't work because it's out of scope?
You are correct that you cannot access your sorted variable from main. But you don't need to. The point of the function is that it modifies the values pointed by its parameters.
For instance:
int main()
{
int x = 5, y = 1, z = 3;
int sum = sumsort(&x, &y, &y);
// now x == 1 , y == 3 , z == 5
}
This is possible. Inside sumsort you need not to create a new array, but to modify the values pointed by it's paramters.
For instance, if you had to sort just two numbers this is what you would do
void foo(int* a, int *b)
{
if (*a > *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
}
You can declare sorted[] as global variable outside of main:
int sorted[3];
main()
{
int a=20, b=15, c=22, sum;
sum= sumsort(&a,&b,&c);
printf("%d",sum);
printf("%d", sorted[0]);
printf("%d", sorted[1]);
printf("%d", sorted[2]);
}
And in your function you can use it as shown below:
int sumsort(int *a, int *b, int *c) {
int sum = *a + *b + *c;
sorted[0] = *a;
sorted[1] = *b;
sorted[2] = *c;
for (int i = 0; i <= 2; i++) {
if (sorted[0] > sorted[1])
{
int temp = sorted[1];
sorted[1] = sorted[0];
sorted[0] = temp;
} // end if
if (sorted[1] > sorted[2])
{
int temp2 = sorted[2];
sorted[2] = sorted[1];
sorted[1] = temp2;
} // end if
} // end for
return sum;
} // end sumsort function
You may have to check your sorting logic.
Hope this helps :)

How to declare multiple pointer-to-pointer using while in C?

I have this code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main(){
/*Start of problem*/
int *a;
int **b = &a;
int ***c = &b;
int ****d = &c;
int *****e = &d;
int ******f = &e;
int *******g = &f;
int ********h = &g;
int *********i = &h;
/*end of problem*/
*********i = 42;
ft_ultimate_ft(i);
return 0;
}
I need to include pointer-to-pointer declaration in the loop (for example, while). It's needed to decrease number of declarations.
I am assuming that I have properly understood you question, which is to create a multiple pointer to a number using a loop and then assign value to it.
I wrote a piece of code that partly completes your requirement but still need to know how many layers there are after the loop.
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main() {
int t = 10;
int n = 8;
void * p = &t;
for (int i = 0; i < n; i++)
{
void* * s = (void **)malloc(sizeof(void*));
*s = p;
p = s;
}
/*end of problem*/
int *********real = (int *********)p;
*********real = 42;
ft_ultimate_ft(real);
return 0;
}
Which outputs 42
The clean up part of the program is not written
PS. In your code, the pointer a is indeterminate and I do not think that your original code can work properly.

Reserving memory using malloc in C

I would like to reserve memory for 3 int arrays in C. All are int types.
Array a is size n, array b is size m and array c is size m.
I have following idea:
void *c;
int *a;
int *b;
int *m;
m = malloc((n + m + m +1) * sizeof(int));
a = n;
b = a + m;
c = b + m;
free(m);
When I try to acces to some of them using syntax for example
a[i] =
I got segmentation fault error.
Here is complete code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void *c;
int *dretve;
int *stol;
int *rez;
int n;
int m;
void *Rezerviraj(void *x){
int c = *((int*)x);
printf("Ušo u funkciju rezerviraj\n");
// sleep(10);
printf("Gotov sam!");
}
int Provjeri(){
int i;
// for(i = n; i < m+n; i++)
// if(stol[i] == 1)
return 0;
return 1;
}
int main(int argc, char *argv[]){
n = atoi(argv[1]);
m = atoi(argv[2]);
int f = 4;
int i = 0;
pthread_t thr_id[2];
c = malloc((n + m + m + 1) * sizeof(int) + n * sizeof(pthread_t));
dretve = n;
stol = dretve + m;
rez = stol + m;
for(i = 0; i < n; i++)
printf("%d ", dretve[i]);
pthread_create(&thr_id[1], NULL, Rezerviraj, &f);
pthread_join(thr_id[1],NULL);
// pthread_create(&thr_id[1], NULL, Rezerviraj,&f);
// pthread_join(thr_id[1],NULL);
// free(c);
return 0;
}
Can someone explain me what is mistake and how can I fix it?
Many thanks!
To allocate memory for 3 arrays of the same type,
int *a_array;
size_t a_count = foo();
int *ba_array;
size_t b_count = foo();
int *c_array;
size_t c_count = foo();
a_array = malloc(sizeof *a_array * (a_count + b_count + c_count));
b_array = a_array + a_count;
c_array = b_array + b_count;
// code uses a_array, b_array, c_array
...
// When done with all 3, only 1 free() call
free(a_array);

Resources