C pointers 2 dimensional move to top - c

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

Related

Find a pair in a struct array only once

I have a struct and a struct array similar to this:
struct point{
double x;
double y;
char name[10];
};
struct point points[1000];
I created an algorithm that calculates the distances between all the points and prints the pair with the smallest distance, like this:
int count = 0;
for (int i = 0; i < 1000; i++){
for(int j = 0; j < 1000; j++){
if(i != j){
double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2));
if(distance == min){
printf("%s - %s\n", points[i].name, points[j].name);
count++;
}
}
}
}
If there are multiple pairs with the same distance, it prints all of them, but it prints them TWICE (the second time in a different order), what would be an ideal logical gate in the printing loop to prevent the structures with the same distance being printed twice?
Change to this:
for (int i = 0; i < 999; i++){
for(int j = i+1; j < 1000; j++){
double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2));
if(distance == min){
printf("%s - %s\n", points[i].name, points[j].name);
count++;
}
}
}
I changed intervals for i and j and removed the if statement.
Instead of looping like this:
for(int i = 0; i < 1000; i++){
struct point a = points[i]
for(int j = 0; j < 1000; j++){
struct point b = points[j]
}
}
Try this so that you only loop over each point once
for(int i = 0; i < 999; i++){
struct point a = points[i]
for(int j = i; j < 1000; j++){
struct point b = points[j]
}
}

How to access a 2d array inside a struct using only pointers

Trying to understand pointers as a beginner in C-
I've got this struct:
typedef struct {
int size; // dimension of array
int **arr; // pointer to heap allocated array
} someStruct;
So I use malloc to generate this struct, and an array, and initialize all the values to zero-
someStruct *m = (someStruct*)malloc(sizeof(someStruct));
m->size = n;
m->arr = (int**)malloc(n * sizeof(int));
// initialize array
for (int i = 0; i < n; i++) {
*(m->arr + i) = (int*)malloc(n * sizeof(int));
// set value to 0
for (int j = 0; j < n; j++) {
*(*(m->arr + i) + j) = 0;
}
}
After this I basically continue to access the array in later stages using the same kind of pointer logic-
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int num = *(*(m->arr + i) + j);
printf("num: %d\n", num);
}
}
Here's the problem- when I try to use this method of access, I'm clearly not getting the right answer- my print output look like this:
num: -2043774080
num: 22031
num: 0
num: 0
...
num: 0
num: 0
Here's the really weird part- this seeming bug of the 'weird' random numbers only comes when I'm creating and accessing an array of size 5-
I've come to believe that the whole
*(*(m->arr + i) + j)
method of access must be wrong- any help on this would be really useful. Thanks in advance, I apologize if this was already answered, my searching was unable to find it.
You should give complete code, but I think I was able to figure out your intent. You have one glaring problem, and many style issues. Here is what I think your code should look like:
typedef struct {
int size; // dimension of array
int **arr; // pointer to heap allocated array
} MagicSquare;
:
:
// no need to dynamically allocate this, it is small
MagicSquare m;
m.size = n;
m.arr = malloc(n * sizeof(int*)); // note it is sizeof(int*), not (int)
// initialize array
for (int i = 0; i < n; i++) {
m.arr[i] = malloc(n * sizeof(int));
// set value to 0
for (int j = 0; j < n; j++) {
m.arr[i][j] = 0;
}
}
:
:
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("num: %d\n", m.arr[i][j]);
}
}
Note that if you want to initialize the allocated memory to zero, you should just use calloc, which does this initialization for you:
// initialize array
for (int i = 0; i < n; i++) {
m.arr[i] = calloc(n,sizeof(int));
}

memory alocation with 2D Array

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

counting negative integers in a matrix

i am having error while running this code
negativenoinmatrix.c:10:16: error: subscripted value is neither array nor pointer nor vector
if(z[i][j]<0)
i want to calculate the number of negative integers in a matrix
#include <stdio.h>
int negnumbers(int *z, int n, int m)
{
int count = 0;
int i = 0;
int j = m - 1;
while (j >= 0 && i < n)
{
if (z[i][j] < 0)
{
count += (j + 1);
i += 1;
}
else
j -= -1;
}
return count;
}
int main()
{
int n = 3, m = 4;
int a[n][m];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
scanf("%d", &a[i][j]);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
printf("%d ", a[i][j]);
printf("\n");
}
int val = negnumbers((int *) a, 3, 4);
printf("%d", val);
}
The function needs to accept a pointer to an array, not a pointer to a single item. Change it to
int negnumbers(int n, int m, int z[n][m])
...
int val = negnumbers(3, 4, a);
(Where int z[n][m], as per the rule of "array adjustment", will get changed by the compiler internally to a pointer to the first element, int (*z)[m].)
When you pass a 2-d array to a function, at least the 2nd dimension must be specified. Change to this:
int negnumbers(int z[][4],int n,int m)
You can then use this more straightforward approach to counting the negative numbers:
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (z[i][j] < 0)
count++;
}
}
You are calling a pointer z, and also creating a dynamic matrix out of it. So you need to allocate some memory for it which can be done with:
malloc(z[i][j])
Then after you're done, make sure you deallocate the memory now or else you'll have a memory leak, which you can read more about at Memory Leaks wikipedia.
This is done by calling free(...)
Hope this solves the not an array or pointer error!

C - How to adapt this code for a very large/dynamic array to a 2 dimensional array?

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?).

Resources