I am facing a question in which I am required to create a function that gets a 2D array and it's size and it should return another 2D array which is basically the same one but half rows size and half columns size and each group of arrays depending on the size of the original matrix will be pasted next to each other, example:
https://imgur.com/a/ctRUopc
image of the faulty output i am getting :
https://imgur.com/a/85q8ipe
it keeps giving me trash value after the second matrix paste for some reason and i dont know why :/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
long long Power(long long C1, long long C2)
{
int Digit = 0, i = 0;
long long Flag, DigitCount=0, Multiplier = 1;
Flag = C2;
while (Flag != 0)
{
Digit = Flag % 10;
DigitCount++;
Flag = Flag / 10;
}
while (i < DigitCount)
{
Multiplier = Multiplier * 10;
i++;
}
long long Final = 0;
Final = (Multiplier * C1) + C2;
return Final;
}
long long** shrink(long long** Matrix, int size, int* pSize)
{
if (size % 2 != 0)
{
return 0;
}
*pSize = size / 2;
long long A, B, C;
long long **New_Matrix = 0;
New_Matrix = (long long**)malloc(*pSize * sizeof(long long*));
for(int i=0; i<*pSize; i++)
{
New_Matrix[i] = (long long*)malloc(*pSize * sizeof(long long));
for (int j = 0; j < *pSize; j++)
{
A = Power(Matrix[2 * i][2 * j], Matrix[2 * i][2 * j + 1]);
B = Power(A, Matrix[2 * i + 1][2 * j]);
C = Power(B, Matrix[2 * i + 1][2 * j + 1]);
}
}
return New_Matrix;
}
int main()
{
long long** Matrix = 0;
int size;
int *pSize;
long long** result=0;
printf("Size Insertion : \n");
scanf("%d", &size);
Matrix = (long long**)malloc(size * sizeof(long long*));
printf("Matrix Insertion : \n");
for (int i = 0; i < size; i++)
{
Matrix[i] = (long long*)malloc(size * sizeof(long long));
for (int j = 0; j < size; j++)
{
scanf("%lld", &Matrix[i][j]);
}
}
printf("Matrix Display : \n");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
printf("%lld ", Matrix[i][j]);
}
printf("\n");
}
result = shrink(Matrix, size, &pSize);
for (int i = 0; i < pSize; i++)
{
for (int j = 0; j < pSize; j++)
{
printf("%lld ", result[i][j]);
}
printf(" \n");
}
free(result, Matrix);
return 0;
}
result = shrink(Matrix, size, &pSize)
Here you're passing the address of the pSize pointer to the function, which when dereferenced, returns the underlying pointer. So the line
*pSize = size / 2; assigns the value to the underlying pointer which is simply wrong. Pointers only hold memory addresses. You may probably have meant to have written this:
**pSize = size / 2;
You should dereference once to get the underlying pointer, twice to get to the variable it points to.
Also, you need to dereference pSize in the for loops as well to get the size value set by the function
for (int i = 0; i < *pSize; i++)
{
for (int j = 0; j < *pSize; j++)
{
printf("%lld ", result[i][j]);
}
printf(" \n");
}
Also, pSize is an empty pointer, it points to an undefined memory address. Make sure that's not the case:
int * pSize = (int *) malloc(sizeof (int));
// rest of code
free(pSize);
Related
I need to create a program that gets a dynamic matrix and changes it to one dimension, for example 4x4 matrix will give 16 arrays length, where each index has a odd or even number, matching the index itself. The threads needs to go over the matrix at the same time and copy the odd and even numbers to the correct places in the array. The main thread needs to wait for the rest of them to finish before printing the array and every value with its respective thread. It should come out like this
We managed to fix the segmentation fault that kept happening, but now we need to set it so that each thread runs right after the other but instead each thread runs 4 times and then it switches to a different one. How can I change it so it'll run as asked?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#define CORE 4
int N;
int odd = 1;
int even = 0;
typedef struct my_thread {
int** matrix;
int* resArray;
int threadId;
int strart_raw;
int strart_cal;
int end_raw;
int end_cal;
int counter;
} my_thread;
void* createArray(struct my_thread* thread);
void main() {
pthread_t th[CORE];
int s_r = 0, s_c, e_r, e_c;
int i, j, lines, columns, * intMatrix;
printf("Type the N for the N*N matrix:\t");
scanf("%d", &N);
int size = N * N;
int result_Array[N * N];
int retcode;
int interval = size / CORE;
int matrix_build_counter = 1;
intMatrix = (int*)malloc(N * N * sizeof(int));
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; ++j)
{
intMatrix[i * N + j] = matrix_build_counter;
matrix_build_counter++;
}
}
printf("The matrix:\n");
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%d ", intMatrix[i * N + j]);
}
printf("\n");
}
struct my_thread thred_obj_array[CORE];
for (int i = 0; i < CORE; i++) {
thred_obj_array[i].matrix = &intMatrix;
thred_obj_array[i].resArray = result_Array;
thred_obj_array[i].threadId = i;
thred_obj_array[i].strart_raw = (int)((i * N) / CORE);
thred_obj_array[i].end_raw = (int)(((interval * (i + 1)) / N));
thred_obj_array[i].strart_cal = ((interval * i)) % N;
thred_obj_array[i].end_cal = ((interval) * (i + 1));
thred_obj_array[i].counter = (int)floor((interval)*i);
}
for (int i = 0; i < CORE; i++) {
retcode = pthread_create(&th[i], NULL, createArray, &thred_obj_array[i]);
if (retcode != 0) {
printf("Create thread failed with error %d\n", retcode);
}
}
printf("done");
for (int i = 0; i < CORE; i++) {
pthread_join(th[i], NULL);
}
printf("the result array is: ");
for (int i = 0; i < N * N; i++) {
printf("%d ", result_Array[i]);
}
}
void* createArray(struct my_thread* thread) {
int j;
for (int i = thread->strart_raw; i < N; i = i * sizeof(int) * N) {
for (j = thread->strart_cal; j < N; j++) {
printf("I am thread: %d And my value is: %d , (%d,%d)\n", thread->threadId, (*thread->matrix + i * N)[j], i, j);
if (((*thread->matrix + i * N)[j]) % 2 == 0) {
thread->resArray[even] = (*thread->matrix + i * N)[j];
even += 2;
printf("-----%d ---even---\n", even);
}
else {
thread->resArray[odd] = (*thread->matrix + i * N)[j];
odd += 2;
printf("---%d ---odd--\n", odd);
}
(thread->counter)++;
if (thread->counter == thread->end_cal) {
return;
}
}
thread->strart_cal = 0;
}
}
int main()
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
printf("%d\n", *(tri[0]));
when I am referencing the tri pointer then it is showing the error.
invalid type argument of unary '*'.
thanks for the answer.
The above part is clarified but I have another issue. but I have another issue
int main()
{
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum,tri[j] / 2);
}
}
printf("%d\n",sum);
return 0;
}
when I am printing the tri[j] it is showing some garbage value.
The variable tri has the type int * due to this declaration
int *tri = (int*)malloc(n * 3 * sizeof(int));
Pay attention to that you allocated an uninitialized memory.
The expression tri[0] has the type int. And you are trying to apply the dereference operator to the expression of the type int
*(tri[0])
So the compiler issues an error.
Instead you could write
int *tri = (int*)calloc(1, n * 3 * sizeof(int));
and then write either
printf("%d\n", tri[0]);
or
printf("%d\n", *tri);
These for loops
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum, tri[j] / 2);
}
}
printf("%d\n",sum);
are incorrect. There are used an incorrect conversion specifier %d instead of %f with the variable sum and incorrect expressions for indices. You need to write
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[3 * i + j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[3 * i + j] / 2;
printf("%f %d\n",sum, tri[3 * i + j] / 2);
}
}
printf("%f\n",sum);
The array expression a[i] is defined as *(a + i) - given some address value a, offset i elements (not bytes!) from that address and dereference the result, so
*tri == *(tri + 0) == tri[0]
The expression tri[0] has type int, which is why the compiler is complaining when you write *(tri[0]); the operand of the unary * operator must have a pointer type.
So in your printf statement you would use either *tri or tri[0]. The type of either expression is int.
As others have said, malloc does not initialize the allocated memory, so the value of tri[0] may be anything. You could use calloc instead, which initializes the memory to all-bits-zero:
int *tri = calloc( n, sizeof *tri );
In C you do not need to cast the result of malloc, calloc, and realloc1, and most of us will advise you to not do so. Similarly, since the type of the expression *tri is int, the result of sizeof *tri is the same as sizeof (int). This way you don't have to worry about keeping types straight between the declaration, the cast, and the sizeof expression, so you're less likely to make a mistake.
This is not the case in C++, but if you're writing C++ you shouldn't be using the C *alloc functions anyway.
How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));
I'm quite new to pointers and C in general.
void moveUpToTop(int num, int dim, int index) {
int i,j;
double *temp = w[index];
double *zero = w[0];
for(i = index; i > 0; i--) {
double *ptrA = w[i];
double *ptrB = w[i - 1];
for(j = 0; j < dim; j++) {
*(ptrA + j) = *(ptrB + j);
}
}
for(j = 0; j < dim; j++) {
*(zero + j) = *(temp + j);
}
}
Having this with a 2-dimensional array w, defined as double **w. I'd like to move some array value with index "index" up to the top of the array using pointers because that is the exercise we've got to do.
first of all, I'm saving one of the array locations, then I'm moving all array locations one level up.
What am I doing wrong?
Given to me is the following code in what I have to design the sort function.
double **w;
int main (void) {
int dim, num;
int i, j;
scanf ("%d %d", &dim, &num);
w = calloc (num, sizeof (double *));
for (i = 0; i < num; i++) {
w[i] = calloc (dim + 1, sizeof (double));
int sum = 0;
for (j = 0; j < dim; j++) {
scanf ("%le", &w[i][j]);
sum += w[i][j] * w[i][j];
}
w[i][dim] = sqrt(sum);
}
sort(num, dim);
for(i = 0; i < num; i++) {
for(j = 0; j < dim; j++) {
printf("%e ", w[i][j]);
}
printf("\n");
}
return 0;
}
Your problem is that you save a pointer to the original data but you don't save the data itself.
double *temp = w[index]; // Here you save the pointer
but in the first loop you overwrite data:
for(i = index; i > 0; i--) {
double *ptrA = w[i]; // Same as w[index] in first loop
double *ptrB = w[i - 1];
for(j = 0; j < dim; j++) {
*(ptrA + j) = *(ptrB + j); // The data pointed to by w[index] is overwritten
// in the first loop
So this code is no copying the original data at index:
for(j = 0; j < dim; j++) {
*(zero + j) = *(temp + j); // Data at index have been overwritten
// so this doesn't do what you want
}
To fix this, it is not sufficient to save a pointer to index(i.e. double *temp = w[index];). Instead you need to save all data that double *temp = w[index]; points to.
So you need to malloc some data to hold a copy. Then copy the data in a for-loop and use the copied data when restoring to zero.
BTW: Also notice that the code given to you uses a very ugly construct. It is allocating dim + 1 to save an extra double. Your move function therefore also need to use dim + 1 instead of just dim
int main()
{
double *array;
long int n;
n=10000000;//10^7
array = (double *) malloc(n*sizeof(double));
return 0;
}
basically, I want to use this code for a really big aray into a 2 dimensional array, which will have dimensions [very large][4].
If you want a 2D array, then allocate a 2D array. It's that simple.
double (*pArr)[4] = malloc(10000000 * sizeof pArr[0]);
Notes:
do not cast the return value of malloc().
use sizeof pArr[0] instead of sizeof(TheDataType) for defensive programming reasons.
This seems working on Wandbox.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double (* array)[4];
long int n;
int i, j;
n=10000000;//10^7
array = (double (*)[4]) malloc(n*sizeof(double[4]));
printf("%u\n",(unsigned int)sizeof(array[0]));
printf("%u\n",(unsigned int)sizeof(double[4]));
for (i = 0; i <n; i++) {
for (j = 0; j < 4; j++) array[i][j] = (double)i * j;
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
for (i = n - 10; i < n; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
free(array);
return 0;
}
int n = 100000;
double** array = malloc(sizeof(double*)*n);
for (int i = 0; i < n; ++i)
{
array[i] = malloc(4*sizeof(double));
}
Also note that we don't cast the malloc's result(Do I cast the result of malloc?).