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!
Related
I've gotten back into C recently after a long absence, and I can't for the life of me remember how to pass a 2D matrix to a function and use it after mallocating it. I believe I've passed the pointer correctly, but I can't seem to actually access anything in the matrix and can't figure out why.
This is what I have written:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
void matrixOperation(int *arr, int m, int n)
{
printf("in matrixOperation\n ");
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n", *((arr+i*n) + j));
}
int main()
{
int i,j,count;
int row, col;
//------------------------------
printf("Number of rows?\n ");
scanf("%d", &row);
printf("Number of columns?\n ");
scanf("%d", &col);
//------------------------------
int* arr[row];
for (i = 0; i < row; i++)
arr[i] = (int*)malloc(col * sizeof(int));
count = 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
arr[i][j] = ++count;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d\n",arr[i][j]);
// We can also use "print(&arr[0][0], m, n);"
matrixOperation((int *)arr, row, col);
for (int i = 0; i < row; i++)
free(arr[i]);
return 0;
}
The goal was to have it accept user input for the size of the matrix, fill each index with a count and then pass it to a function which would print it out. However when I try it the print statement just outputs random numbers which I assume are what the pointers are pointing at.
I would like matrixOperation to print out the same thing as the print statement in main and I can't quite figure out what I've done wrong.
Change the function signature and you should be able to use the same piece of code.
void matrixOperation(int **arr, int m, int n)
{
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n",arr[i][j]);
}
Call with:
matrixOperation(arr, row, col);
Remember when an array is passed to a function, it "decays" into a pointer. You have an array of pointers. That decays to a pointer to pointers.
You declared an array of pointers:
int* arr[row];
So pass this array to the function.
The function will be declared like:
void matrixOperation(int **arr, int m, int n)
{
printf("in matrixOperation\n ");
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n", *( *( arr + i ) + j ) );
}
and call the function like:
matrixOperation( arr, row, col );
Though it will be better to define the function like:
void matrixOperation(int **arr, int m, int n)
{
printf("in matrixOperation\n ");
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < n; j++ )
{
printf("%d ", *( *( arr + i ) + j ) );
}
putchar( '\n' );
}
}
Pay attention to that this expression with the pointer arithmetic:
*( *( arr + i ) + j )
can be rewritten using the subscript operator the following way:
arr[i][j]
The both expressions are equivalent each other.
As for your call of the function with casting the array designator:
matrixOperation((int *)arr, row, col);
then it is wrong because you do not have one extent of memory. You allocated several extents of memory.
#define N 3
int subMatrix(int a[][N]) {
int i, j;
int sum = 0;
int arr[N];
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
return *arr;
}
void main() {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
for (int i = 0; i < N; i++) {
printf("%5d", subMatrix(a[i]));
}
}
The function works fine, the problem is when I'm returning the new array and loop over it in the main function I get the first element of the array and the other elements are addresses.
i did it before with another array with size of doubles and it worked.
There is something i miss?
double avgMatrix(int a[][C]) {
int i, j, sum=0;
double M[R];
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
sum += a[i][j];
}
M[i] = (double)sum / C;
sum = 0;
}
return *M;
}
void main() {
int a[R][C] = {
{9,2,4},
{3,8,11},
{3,1,2}
};
for (int i = 0; i < R; i++)
printf("%5.2lf", avgMatrix(a[i]));
}
this code works. what can be the difference?
I do not really understand what your function subMatrix does.
Your code needs a few modifications to be able to compile.
First, include the necessary header #include <stdio.h>, because your code needs printf.
Second, make sure the passed parameter and the attribute be the same type.
Third, if you would like to return an array from a function, you should use dynamic allocation function to help you do that. malloc
/* At least, make sure to include necessary head files
* #include <stdio.h>
*/
#define N 3
int subMatrix(int a[][N]) {
int i, j;
int sum = 0;
int arr[N];
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
/* Because the passed parameter is one dimensional
* so the following code does not make sense.
*/
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
/* arr is a local variable. It is actually a pointer
* It should never be returned.
* In fact, *arr is only the first element of the array of arr.
* At least, you should return the address of the first element.
* Considering your purpose, to use dynamic allocation is proper.
*/
return *arr;
}
/* 'void main()' is not right.
* 'int main(void)' is the right way.
*/
void main() {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
for (int i = 0; i < N; i++) {
/* a[i] is a one-dimensional array,
* but subMatrix needs a two dimensional one.
*/
printf("%5d", subMatrix(a[i]));
}
}
A possible working code:
#include <stdio.h>
#include <stdlib.h>
#define N 3
int *subMatrix(int a[N][N]) {
int sum = 0;
int *arr = (int *)malloc(N*sizeof(int));
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
return arr;
}
int main(void) {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
int *arr = subMatrix(a);
for (int i = 0; i < N; i++)
printf("arr[%d] : %d\n", i, arr[i]);
free(arr);
}
Is this what you want? Try it.
I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0
Given two arrays: int nums[N] and int *ptrs[N] (N is a constant number).
I have to initialize the first array with some numbers. After that, i have to initialize the second array, so every element of the second array points to the element with the same index of the first array. (ptrs[0] points to nums[0],...).
Now i have to write a function with "ptrs" as argument that modifies the pointers in such a way that the first element of the second array points to the smallest number in the first array,..)
It's not allowed to change the "nums-array", i can only change the "ptrs-array".
This is my code i already have, but when i run it, the "nums-array" changes too.
What do i do wrong?
#include <stdio.h>
#define N 6
void sort(int *ptrs);
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int(*ptrs)[N];
int i;
ptrs = nums;
sort(ptrs);
for (i = 0; i < N; i++)
printf("nummer is: %d en %d\n", (*ptrs)[i], nums[i]);
return 0;
}
void sort(int *ptrs)
{
int i, j, tmp;
for (i = 0; i < N; i++)
for (j = i + 1; j < N; j++)
if ((ptrs)[i] > (ptrs)[j])
{
tmp = (ptrs)[i];
(ptrs)[i] = (ptrs)[j];
(ptrs)[j] = tmp;
}
}
Fix for the first part:
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int *ptrs[N]; // fix
int i;
for(i = 0; i < N; i++) // fix
ptr[i] = nums+i; // fix (or ptr[i] = &nums[i])
I found the solution, thanks for helping guys!
#include <stdio.h>
#define N 6
void sort(int ptrs[], int nums[]);
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int i,j,*p, *ptrs[N];
for (i = 0; i < N; i++) {
ptrs[i] = &nums[i];
}
sort(ptrs, nums);
return 0;
}
void sort(int *ptrs[], int nums[])
{
int i, j, tmp, p[N];
for (i = 0; i < N; i++)
p[i] = *ptrs[i];
for(j = 0; j < N; j++)
for (i = 0; i <= N; i++)
if (p[i] > p[i+1])
{
tmp = (ptrs)[i];
(ptrs)[i] = (ptrs)[i+1];
(ptrs)[i+1] = tmp;
for (i = 0; i < N; i++)
p[i] = *ptrs[i];
}
for (i = 0; i < N; i++)
printf("nummer is: %d en %d\n", *ptrs[i], nums[i]);
return;
}
Hello i am trying to use counting sort to sort numbers that i read from a file. this is my code:
void CountingSort(int array[], int k, int n)
{
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++)
{
C[i] = 0;
}
for (j = 1; j <= n; j++)
{
C[array[j]] = C[array[j]] + 1;
}
for (i = 1; i <= k; i++)
{
C[i] = C[i] + C[i-1];
}
for (j = 1; j <= n; j++)
{
B[C[array[j]]] = array[j];
C[array[j]] = C[array[j]] - 1;
}
printf("The Sorted array is : ");
for (i = 1; i <= n; i++)
{
printf("%d ", B[i]);
}
}
void max(int array[],int *k,int n){
int i;
printf("n je %d\n",n);
for (i = 0; i < n; i++)
{
if (array[i] > *k) {
*k = array[i];
}
}
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k=0,n,x,z;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
max(array,&k,n);
printf("Max je %d\n",k);
CountingSort(array,k,n);
return 0;
}
i have no errors but when i start my program i get Segmentation fault error. pls help! (dont read this bot is asking me to write some more details but i have none so i just write some random words so i can post my question and hopefully get an answer)
The problem is that your implementation of the counting sort is incorrect: it uses arrays as if they were one-based, while in C they are zero-based.
After carefully going through your loops and fixing all situations where you use a for loop that goes 1..k, inclusive, instead of the correct 0..k-1, the code starts to work fine:
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++){
C[i] = 0;
}
for (j = 0; j < n; j++){
C[array[j]]++;
}
for (i = 1; i <= k; i++){
C[i] += C[i-1];
}
for (j = 0; j < n; j++) {
B[--C[array[j]]] = array[j];
}
printf("The Sorted array is : ");
for (i = 0; i < n; i++) {
printf("%d ", B[i]);
}
Demo.
Note: I modified some of the operations to use C-style compound assignments and increments/decrements, e.g. C[array[j]]++ in place of C[array[j]] = C[array[j]] + 1 etc.
The problem most likely is here
int B[100], C[1000]; // C has space for numbers up to 999
...
for (i = 1; i <= k; i++)
C[i] = C[i] + C[i-1]; // adding up till C[k] == sum(array)
for (j = 0; j < n; j++)
B[C[array[j]]] = array[j]; // B has space up to 99, but C[k] is sum(array)
so you're reserving space for C for a highest value of 999 but in B you're assuming that the sum of all input values is less than 100...
the resolution of your problem is to first probe the input array and get the maximum and the sum of all input values (and minimum if the range may be negative) and allocate space accordingly
edit: you probably meant j < n and not j <= n
Adding to dasblinkenlight's spot-on answer:
Is your input data guaranteed to be in the range [0, 999]? If it isn't, it's obvious that segmentation faults can and will occur. Assume that the maximum value of array is 1000. C is declared as
int C[1000];
which means that C's valid indices are 0, 1, 2, ... 999. But, at some point, you will have the following:
C[array[j]] = ... /* whatever */
where array[j] > 999 so you will be attempting an out-of-bounds memory access. The solution is simple: probe array for its maximum value and use dynamic memory allocation via malloc:
/* assuming k is the maximum value */
int * C = malloc((k + 1) * sizeof(int));
Note: an alternative to this, which would also nullify the need for an initialization loop to make all elements of C equal to 0, would be to use calloc, which dynamically allocates memory set to 0.
// allocate C with elements set to 0
int * C = calloc(k + 1, sizeof(int);
Another important factor is the range of your running indices: you seem to have forgotten that arrays in C are indexed starting from 0. To traverse an array of length K, you would do:
for (i = 0; i < K; ++i)
{
processArray(array[i]);
}
instead of
for (i = 1; i <= K; ++i)
{
processArray(array[i]);
}