I use gsl random generator to generate 2 big matrices, and use gsl cblas to multiply them, but I always got Segmentation fault when the cblas operation begins. When I can't solve this, I then write the code below, using the very basic idea to do matrix multiplication, and I still got Segmentation Fault, but all the two can work all right when matrix is really a small one, I'm really puzzled about this.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
void GenerateKey(int m, int n, int l, int q, float alpha)
{
// initialization
int i;
int j;
int k;
float *A;
float *S;
float *E;
float *B;
float sigma = (alpha * q ) / sqrt(2 * PI);
A=(float*)malloc(sizeof(float)*(m*n));
S=(float*)malloc(sizeof(float)*(n*l));
B=(float*)malloc(sizeof(float)*(m*l));
E=(float*)malloc(sizeof(float)*(m*l));
// init A
for(i = 0; i < m*n; i++)
{
A[i]=0;
}
printf("\n");
// init S
for(i = 0; i < n*l; i++)
{
S[i]=0;
}
printf("\n");
// init E
for(i = 0; i < m*l; i++)
{
E[i]=0;
}
printf("\n");
float po;
for(i = 0; i < m; i++)
{
for(j=0; j<l; j++)
{
po=0;
for(k=0; k<n; k++)
{
po +=A[i*m+k]*S[k*n+j];
}
po += E[i*m +j];
B[i*m+j]=((int)po) % q;
}
}
printf("Game over");
printf("\n");
free(A);
free(B);
free(S);
free(E);
}
int main()
{
GenerateKey(2680,191,64,72973,0.000551);
return 0;
}
When you're doing i*m+j, shouldn't that be i*l+j ? Similarly with i*m+k should be i*l+k and k*n+j should be k*l+j
The reason being, take for example E = (float*)malloc(sizeof(float)*(m*l)), so you have m rows and l columns (or vise versa), so if you are iterating over the m dimension you need to be multiplying your m iterator (i in this case) by the stride of your matrix in that dimension, which is l.
You don't check the malloc() return values, so my guess is that one or more allocation is failing and you're dereferencing NULL. Another possibility is of course an indexing error, so you acccess out of bounds.
You incorrectly compute an element index for all the matrices.
When you have an MxN matrix which is allocated as an 1-dimensional array, the index for an element (i,j) is i*N+j. Instead, you're computing it as i*M+j.
Related
I have written a code which calculates the transpose of a matrix NxM using double pointers.
As long as the matrix is square(NxN) it works without problems, but if it isn't, I get this error:
Exception thrown at 0x00052580 in ConsoleApplication27.exe: 0xC0000005: Access violation writing location 0xFDFDFDFD. If there is a handler for this exception, the program may be safely continued.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int **alloc(int r, int c) {
int **d;
d = (int **)malloc(r * sizeof(int *));
for (int i = 0; i < r; i++) {
d[i] = (int *)malloc(c * sizeof(int));
}
return d;
}
void input(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("[%d][%d]=", i, j);
scanf("%d", &A[i][j]);
}
}
}
void output(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
}
void transpose(int **A, int r, int c) {
int **T = alloc(r, c);
int i, j;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
T[j][i] = A[i][j];
output(T, c, r);
}
void main()
{
int r,c;
scanf("%d%d",&r,&c);
int **A=alloc(r,c);
input(A, r, c);
printf("The transpose of the matrix is: \n");
transpose(A, r, c);
}
Could you point and fix my error for me? I've run this in Visual Studio 2015 and I get that error, and on https://www.onlinegdb.com I get Segmentation fault (core dumped)
int **T = alloc(r, c);
I'd start by looking at the line of code shown above. If you're transposing an RxC matrix, you probably want the target to be CxR. Otherwise, you're likely to run off the end of one of the dimensions.
Anything beyond that, you probably want to learn to use the debugger, which is particularly good in Visual Studio. Single-stepping through the code and keeping an eye on the relevant variables is a valuable skill to learn.
As an aside, there are two other things that can cause problems with your code:
In C, you should not cast the return value from memory allocation functions, that can introduce certain subtle errors; and
You should check the return value of memory allocation functions to ensure they haven't failed.
Neither of those are very likely in this case, unless your matrices are massive, but it's a good habit to get into.
My function should randomly insert a user-chosen number of 1 into my matrix. The difficulty lies in the fact that if a cell contains a 1 the cells around it must be set to 0. Why my code print a wrong number of 1? In the code below I had thought to first set the entire matrix to 0, then randomly generate a cell to be set to 1, after having checked it contains 0 and the distance between this cell and other cells containing 1 is >= 1. All this is done until the number m entered by the user becomes 0.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void initialize(int n, int a[n][n]);
void createMap(int n, int a[n][n], int m);
int check (int i, int j, int v, int w);
void print(int n, int a[n][n]);
int main(){
int n;
printf("Insert square matrix size: ");
scanf("%d", &n);
int m;
printf("Insert 1s number: ");
scanf("%d", &m);
int a[n][n];
initialize(n,a);
createMap(n,a,m);
}
//Filling the matrix with 0
void initialize(int n, int a[n][n]){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
a[i][j] = 0;
}
}
}
//Setting in random position 1 value
void createMap(int n, int a[n][n], int m){
int x1; int x2;
int b[0][0];
while (m > 0){
int i = rand() % n;
int j = rand() % n;
if (a[i][j] == 0 && (check(i,j,x1,x2) == 1)){
a[i][j] = 1;
m--;
//I have to fill b array with coordinates and then to pass
//b array to check function to do the check in the whole b array
}
}
print(n,a);
}
//checking if I can set the value to 1
int check (int x1, int y1, int x2, int y2){
if (sqrt(pow((x1-x2),2) + pow((y1-y2),2)) >= 1){
return 1;
} else {
return 0;
}
}
//Printing the matrix
void print(int n, int a[n][n]){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
printf("\t%d",a[i][j]);
}
puts("");
}
}
After generating the coordinates i and j, you should calculate the distance between that cell and the other cells set to 1. You can use the Manhattan formula to do that.
If the distance between the newly generated cell and the other cells set to 1 is grater than or equal to 1, you can go ahead and generate the other ones, otherwise you should set it back to zero and generate new coordinates.
This is homework right?
A few issues:
You have a variable matrix that you don't use.
You set a[k][l] = 1; before you know what the old value was, and therefore can't tell if m should be incremented or not.
Your bounds checking is messy, it is difficult to see if it is correct, and if you update m and all array elements around a[k][l] correctly. Nobody wants to look at messy code, unless they get paid. They will just assume that it is wrong. So that part of the code is by definition wrong, and nobody can tell you why.
Your bounds checking assumes you have a 4x4 array.
... and a few others.
Point 1 is easy to fix, and it is not important. It just adds to the ugliness of your code.
Point 2 is solved by only updating a[k][l] and m if a[k][l] was zero:
if (a[k][l] == 0)
{
a[k][l] = 1;
m--;
}
Point 3 can be most easily fixed by creating a separate function that does resetting of single array elements with bounds checking. Since I assume this is homework, I am not going to write this for you, unless you have made an honest try yourself first. The function signature could look like this:
/*
Set value of `a[line][column]` to zero and increment `*m` if value
was changed.
Nothing is done if `line` or `column` are out of bounds.
*/
void matrix_element_reset(int n, a[n][n], int line, int column, int *m);
You can then easily reset array elements around a[k][l] like this:
/* This can be simplified with loops */
matrix_element_reset(n, a, k-1, l, &m);
matrix_element_reset(n, a, k, l, &m);
matrix_element_reset(n, a, k+1, l, &m);
.....
Point 4: Your variable n stores the dimension of your matrix. Use it.
I'm making a randomized n*n matrix, but I do not know the value of n until the program is already running.
I'm capable of creating the n*n matrices in main() like so:
double (*m1)[n];
m1 = malloc(sizeof *m1 * n);
double (*m2)[n];
m2 = malloc(sizeof *m2 * n);
But now I must use these matrices outside of main and need them to be global, but I'm completely clueless how to make them global. I intend to read these two matrices with multiple threads and need them easily accessible. I know I can make a struct to pass multiple parameters, but I would need to define a struct with variable length arrays globally so the problem rearises. Thank you for your time.
Just declare as double pointer and allocate memory in main. For more details refer this
#include <stdio.h>
int **a;
void fun(int n)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
printf("%d ",a[i][j]);
}
}
int main(void)
{
int n;
scanf("%d",&n);
a = (int **)malloc(n * sizeof(int *));
for(int i=0;i<5;i++)
{
a[i]=(int*)malloc(n*sizeof(int));
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
fun(n);
return 0;
}
Working Code : https://ideone.com/OMQ4qA
The correct, proper solution is to not use globals. Allocate the array in the thread which will persist throughout the execution of the whole program.
If that, for reasons unknown, is not an option, then you will have to come up with some solution that stores the array size globally too. You could create a simple ADT for this, such as a struct with a "mangled" 2D array in the form of a flexible array member. Example:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
size_t x;
size_t y;
double array [];
} double_array2d_t;
double_array2d_t* array2d = NULL;
int main()
{
/* let x and y be some manner of run-time values: */
int x = 3;
int y = 2;
array2d = malloc(sizeof(*array2d) + sizeof(double[x][y]));
array2d->x = x;
array2d->y = y;
double count = 0.0;
for(int i=0; i<x; i++)
{
for(int j=0; j<y; j++)
{
array2d->array[i*y + j] = count++;
printf("%f ", array2d->array[i*y + j]);
}
printf("\n");
}
...
free(array2d);
}
And of course if you access this from multiple threads, you have to protect the data with a mutex as always.
So i´m trying to solve a hackerrank problem (C language) where you perform k array[n] rotations, and at the end, ask for a m and print array[m].
My program is probably correct (it runs perfectly for most of tests, but some of them terminate due to timeout) , but inefficient, don´t know how to improve it.
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int main(){
int n;
int k;
int q;
scanf("%d %d %d",&n,&k,&q);
int *a = malloc(sizeof(int) * n);
int *b = malloc(sizeof(int) * n);
for(int a_i = 0; a_i < n; a_i++){
scanf("%d",&a[a_i]);
}
for(int i = 0; i < k; i++){
b[0] = a[n-1];
for(int a_i = 1; a_i < n; a_i++){
b[a_i] = a[a_i-1];
}
for(int a_i = 0; a_i < n; a_i++) a[a_i] = b[a_i];
}
for(int a0 = 0; a0 < q; a0++){
int m;
scanf("%d",&m);
printf("%d\n", b[m]);
}
return 0;
}
This looks more like an algorithms question. From what I gather, your program:
reads an array of size n;
rotates the array k positions to the right;
prints q positions from the resulting array.
The complexity is O(kn + q) because each of the k rotations is done in linear time.
You can do step 2 with just one rotation. Copy the last k elements from a to the beginning of b and the first n-k elements from a to the end of b. This decreases the complexity to O(n + q).
You can further optimize the program by skipping step 2 altogether. When looking up position m in step 3, just look at a[k - m] (and wrap around if k < m). This decreases the complexity to O(q).
I am trying to create a data structure to store a matrix and write a routine to generate a square matrix of random numbers.
Here is my code. I am strangely getting only 2 float numbers as output. I am doing all this to implement strassen matrix multiplication, which is why I added rs, re, cs, ce to struct.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _matrix {
int rs;
int re;
int cs;
int ce;
float a[100][100];
}matrix;
void display(matrix m)
{
int i, j;
for (i=m.rs ; i<=m.re ; i++) {
for (j=m.cs ; j<=m.ce ; j++)
printf("%f", m.a[i][j]);
printf("\n");
}
printf("\n");
return;
}
matrix random_matrix(int n)
{
matrix random;
random.cs = random.rs = 0;
random.rs = random.re = n -1;
int i, j;
for(i=0; i < n; i++){
for(j = 0; j < n; j++)
random.a[i][j] = rand();
}
return random;
}
int main(void)
{
matrix m1 = random_matrix(3);
matrix m2 = random_matrix(3);
display(m1);
display(m2);
return 0;
}
I think, to fit the logic, in your code, in random_matrix() function,
random.rs = random.re = n -1;
should be
random.ce = random.re = n -1;
Otherwise, in display(), for (i=m.rs ; i<=m.re ; i++) does not make sense.
That said, to see the random number generator, you can call srand(time(NULL)); in main(), before the call to the matrix generation functions.