Allocating a 2d Array - c

My aim is to allocate a 2d array with only using 1 line for efficiency. Since my prof is expecting it to be efficient.
the code gives me an error saying that it can't convert from void* to int.
#include<stdio.h>
#include<stdlib.h>
#define NUMOFCOL 4
int **addtwoarr(int (*A)[NUMOFCOL], int (*B)[NUMOFCOL]);
int main(void){
int firstarr[4][4]={{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1}},
secondarr[4][4]={{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1}}, **receiver;
receiver = addtwoarr(firstarr, secondarr);
printf("%d", receiver[3][3]);
}
int **addtwoarr(int (*A)[NUMOFCOL], int (*B)[NUMOFCOL]){
int col, row, **arr;
(*arr)[NUMOFCOL] = malloc(NUMOFCOL * sizeof(*arr)); /*this line in particular gives the error */
for(row=0; row<NUMOFCOL; row++){
for(col=0;col<NUMOFCOL; arr[row][col]=A[row][col]+B[row][col], col++){}
}
return arr;
}
The allocation happens in the addtwoarr function which is where the error occurs.

I seriously don't recommend this, as there are a ton of assumptions in your code about top-end sizing. But if you really want to do it, the rather cryptic syntax for returning pointers to fixed length arrays in C looks something like this:
#include <stdio.h>
#include <stdlib.h>
#define NUMOFCOL 4
int (*addtwoarr(int A[][NUMOFCOL], int B[][NUMOFCOL]))[NUMOFCOL];
int main(void)
{
int firstarr[][NUMOFCOL] = {
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1}},
secondarr[][NUMOFCOL] = {
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1}};
int (*receiver)[NUMOFCOL] = addtwoarr(firstarr, secondarr);
printf("%d\n", receiver[3][3]);
free(receiver);
}
int (*addtwoarr(int A[][NUMOFCOL], int B[][NUMOFCOL]))[NUMOFCOL]
{
int col, row;
int (*arr)[NUMOFCOL] = malloc(NUMOFCOL * sizeof(*arr));
for(row=0; row<NUMOFCOL; row++){
for(col=0;col<NUMOFCOL; arr[row][col]=A[row][col]+B[row][col], col++);
}
return arr;
}
Output
2
Best of luck.

Related

Selection Sort algorithm in C doesn't print the entire sorted array

#include <stdio.h>
#include <stdlib.h>
int smallest(int [],int);
int select_sort(int[],int);
int smallest(int arr[],int len){
int small_index=0;
int small=arr[0];
for(int i=0;i<len;i++){
if(arr[i]<small){small=arr[i];
small_index=i;
}
}
return small_index;
}
int select_sort(int arra[],int len){
int new_arra[100];
for(int i=0;i<len;i++){
int small=smallest(arra,len);
new_arra[i]=arra[small];
printf("%d",new_arra[i]);
}
return new_arra;
}
int main()
{
int arr[100]={6,1,0,-2,18};
select_sort(arr,5);
return 0;
}
I wrote this code for the selection sorting program and i know ideally i should be using the dynamic allocation for arrays in the select_sort function, but i was attempting it without it. It is supposed to print the array in an ascending order and I think I am messing up variable assignment somewhere, because when i run the program it only prints the smallest integer of the input array len number of times and not the rest of them.
If you don't mind messing up with your initial array, you can do:
int select_sort(int arra[],int len)
{
int maxValue = Integer.Max_Value;
int new_arra[100];
for(int i=0;i<len;i++){
int small=smallest(arra,len);
new_arra[i]=arra[small];
arra[small]= maxValue;
printf("%d",new_arra[i]);
}
return new_arra;
bear in mind that this is highly unefficient

How do I pass in a 2d array I made from main into another function in C

so I'm trying to make a 2d binary matrix that is the size provided by stdin and that has randomly assigned indexes for the 0 and 1, however, their cannot be more than size/2 zeroes or ones.
For example
an input of 2
could output
1 0
0 1
Now I was going to originally just use the argument int arr[][n] in init but this idea failed since passing in the matrix just resulted in my program going on some sort of an infinite loop when I attempted to access matrix again inside of the main function. I believe this happened because the lifespan of matrix expired when init concluded? So my question here is why is what I'm doing now producing the below error and how can I fix this up?
note: expected ‘int * (*)[(sizetype)(n)]’ but argument is of type ‘int (*)[(sizetype)(dim)][(sizetype)(dim)]’
7 | int init(int n, int* arr[][n]);
My code
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int init(int n, int* arr[][n]);
int main(){
time_t t;
srand((unsigned) time(&t));
int dim;
printf("Enter a positive even integer: ");
scanf("%d",&dim);
if(dim<2||dim>80){
return 1;
}
int matrix[dim][dim];
init(dim,&matrix);
return 0;
}
int init(int n, int* arr[][n]){
int numZeroes,numOnes;
int zero_or_one;
for(int row=0;row<n;row++){
numZeroes=0;
numOnes=0;
for(int col=0;col<n;col++){
if(numZeroes<n/2 && numOnes<n/2){
zero_or_one=rand()%2;
*arr[row][col]=zero_or_one;
if(zero_or_one==1){
numOnes++;
}
if(zero_or_one==0){
numZeroes++;
}
}
else{
if(numZeroes==n/2 && numOnes<n/2){
*arr[row][col]=1;
}
if(numZeroes<n/2 && numOnes==n/2){
*arr[row][col]=0;
}
}
}
}
for(int row=0;row<n;row++){
for(int col=0;col<n;col++){
printf("%d ",*arr[row][col]);
}
printf("\n");
}
return 0;
}
The function should be declared like
void init(int n, int arr[][n]);
(the return type int of the function does not make a great sense.)
and called like
init(dim, matrix);
Within the function instead of statements like this
*arr[row][col]=zero_or_one;
you have to write
arr[row][col]=zero_or_one;

Code crashes at the printf statement

The code runs until it reaches the statement:
printf("%d", sumOccur(input));
The code:
#include <stdio.h>
#include <stdlib.h>
int sumOccur(int A[]);
int main(){
int input[6] = {1,1,1,2,2,3};
printf("%d", sumOccur(input));
return 0;
}
int sumOccur(int A[]) {
int sum, i;
while(A[i]!='\0'){
sum += A[i];
i++;
}
return sum;
}
If I have made any silly mistakes please oblige.
It's not the printf() crashing. It's sumOccur(). Your array has no \0 value in it, so your while() never terminates and you end up in a near-infinite loop and run off the end of the array.
The array is an array of numbers, not a string, so there is no reason whatsoever to think there there would be a null-terminator on the values. null terminators are for strings, not arrays of numbers.
In your function int sumOccur you have two problems-
1. sum and i are not initialized just declared. Initialize both to 0 .
2. Also while(A[i]!='\0') ain't going to work as expected as your array doesn't have that value in it.
Your code invokes undefined behaviour: you access A[6] and subsequent inexistent entries in sumOccur trying to find a final 0 in the array, but you do not put one in the definition of input in the main function.
-------- cut here if you are not interested in gory implementation details --------
The array is allocated on the stack, very near the top since it is instantiated in the main function. Reading beyond the end until you find a 0 likely tries to read beyond the end of the stack pages and causes a segmentation fault.
Note that you are dealing with an int array,which means it normally won't contain '\0' character.To iterate over the array you need to specify number of elements.Here is the correct way :
#include <stdio.h>
#include <stdlib.h>
int sumOccur(int A[],size_t number_of_elemets);
int main(){
int input[6] = {1,1,1,2,2,3};
//Get the number of elements
size_t n = sizeof(input) / sizeof(int);
printf("%d", sumOccur(input,n));
return 0;
}
int sumOccur(int A[],size_t number_of_elements) {
int sum = 0;
size_t i = 0;
while( i < number_of_elements )
{
sum += A[i];
i++;
}
return sum;
}
You are iterating while A[i] != '\0' but there is no '\0' in the array and also you never initialize sum which is unlikely the cause for a crash but it could be.
You need to pass the number of elements in the array, like this
#include <stdio.h>
#include <stdlib.h>
int sumOccur(size_t count, const int *A);
int sumOccurCHQrlieWay(const int *A, size_t count);
int main()
{
int input[] = {1, 1, 1, 2, 2, 3};
printf("%d", sumOccur(sizeof(input) / sizeof(*input), input));
return 0;
}
int sumOccur(size_t count, const int *A)
{
int sum;
sum = 0;
for (size_t i = 0 ; i < count ; ++i)
sum += A[i];
return sum;
}
int sumOccurCHQrlieWay(const int *A, size_t count)
{
return sumOccur(count, A);
}

Unhandled exception... Access Violation reading location

I'm following a tutorial on using NVIDIA/CUDA/etc. here: http://www.nvidia.com/content/gtc-2010/pdfs/2131_gtc2010.pdf
I'm trying to add two vectors in parallel, but I am having trouble with these memory access violations mentioned in the title of my post.
The error is occurring at my printf line (I will post my code below), but if I comment it out I get taken to a file named "dbgheap.c" and I just get the same error message on line 1696 of that file (the file has 3268 lines)
The line is:
if (*pb++ != bCheck)
and the function that is in is:
extern "C" static int __cdecl CheckBytes(
unsigned char * pb,
unsigned char bCheck,
size_t nSize
)
{
while (nSize--)
{
if (*pb++ != bCheck) //this is the line with the error
{
return FALSE;
}
}
return TRUE;
}
And the memory address location it says it can't access, I believe, are the locations of my "a", "b", and "c" variables (will post my code below).
So without further adieu, here is my code (sorry there are no comments):
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#define N 10
__global__ void kernel() {
}
__global__ void add(int *a, int *b, int *c) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
void random_ints(int* a,int num) {
for (int i = 0; i<num; i++)
a[i] = rand();
}
int main () {
int *a,*b,*c;
int *dev_a, *dev_b, *dev_c;
int size = N*sizeof(int);
cudaMalloc((void**)&dev_a,size);
cudaMalloc((void**)&dev_b,size);
cudaMalloc((void**)&dev_c,size);
a = (int*)malloc(size);
b = (int*)malloc(size);
c = (int*)malloc(size);
random_ints(a,N);
random_ints(b,N);
cudaMemcpy(dev_a,&a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,&b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(&c,dev_c,size,cudaMemcpyDeviceToHost);
for (int i = 0; i<N; i++)
printf("%d + %d = %d\n",a[i],b[i],c[i]);
free(a); free(b); free(c);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
If you need any clarifications just ask.
Thanks!
The cudaMemcpy parameters are the actual pointers so no need to take their address before passing (unlike cudaMalloc). Remove the &.
cudaMemcpy(dev_a,a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(c,dev_c,size,cudaMemcpyDeviceToHost);
I believe this is what is causing your memory corruption problems.
As a matter of form, I'd pass the length in and check it against blockIdx.x.
__global__ void add(int *a, int *b, int *c, int N) {
if (blockIdx.x < N) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
}
I thought this was actually required but I'm guessing it isn't if the range fits in a single warp. For N > 16, it will be necessary and the check will be a bit more complex (using threadIdx.x and blockDim.x).

passing statically allocated 2D arrays as function arguments in C

Consider this code:
#include <stdio.h>
#define N 5
void printMatrix(int (*matrix)[N],int n)
{
int i,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%d",matrix[i][j]);
printf("\n");
}
}
int main()
{
int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
printMatrix(R,3);
}
This works fine as expected.
Now, I thought to write the functions handling 2D-matrices in a separate source file and link them wherever required.
But then I ran into a problem as in the function printMatrix, the size of array of int to which matrix points (i.e N) is required at compile-time. So, my functions would not work in other cases when the size is different.
So,How can I handle this?
Dynamic Arrays are a solution but i want to know if it can be done with static arrays.
You can't use the built-in 2D array type if both sizes are not known at compile time. A built-in 2D array must have at least one of the two sizes known at compile time.
If both sizes are run-time values, then you have no other choice but to use a "manual" implementation of 2D array, like an array of pointers to arrays, for example. In that case the function declaration might look as follows (two alternative equivalent forms)
void printMatrix(int *const *matrix, int n, int m);
void printMatrix(int *const matrix[], int n, int m);
To access to the array elements you can still use the "traditional" syntax
matrix[i][j]
The array itself would be created as follows (a simple example)
int row0[] = { 1, 2, 3 };
int row1[] = { 4, 5, 6 };
int *matrix[2];
matrix[0] = row0;
matrix[1] = row1;
printMatrix(matrix, 2, 3);
But if you already have a matrix implemented as a built-in 2d array
int matrix[2][3] = { ... };
then just to be able to pass it to the above function you can "convert" it into the above form by using an additional temporary "row pointer" array
int *rows[2];
rows[0] = matrix[0];
rows[1] = matrix[1];
printMatrix(rows, 2, 3);
Write yourself a macro:
#define MAT(i,j) matrix[i*n + j];
and declare "matrix" as a simple pointer to an "int".
Calculate the array index yourself. This will handle an arbitrary two dimensional array, for example:
void printMatrix(int *matrix,int n, int m)
{
int i,j;
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%d",matrix[m * i + j]);
printf("\n");
}
}
Don't try to pass it as a 2-D array; pass a pointer to the first element, then compute offsets manually:
void printMatrix(int *a, size_t m, size_t n)
{
size_t i,j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("a[%lu][%lu] = %d\n",
(unsigned long) i,
(unsigned long) j,
a[i*n+j]); // treat a as 1-d array, compute offset manually
}
}
}
int main(void)
{
int arr[5][4];
...
printMatrix(&arr[0][0], 5, 4);
...
}
Granted, this will only work for contiguously allocated arrays.
Although the syntax is not exactly the same, but this also happens to work a bit:
#include <stdio.h>
#define N 5
void printMatrix(int* row,int n,int sz)
{
int i,j;
int *currRow;
for(i=0;i<n;i++){
currRow = row+i*sz;
for(j=0;j<n;j++)
printf("%d",currRow[j]);
printf("\n");
}
}
int main()
{
int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
printMatrix(R[0],3,sizeof(R[0])/sizeof(int));
}

Resources