Using free() creates segmentation fault - c

I'm having an issue that I cannot seem to fix with my memory allocations.
I create 3 dynamically allocated arrays (ipiv,k,b) using malloc, but when I try and free them, I get a seg fault. If I don't free them, the code works fine (but if I run too many iterations, I run out of memory).
Here is the code... I've taken out all of the parts that do not use the 3 arrays, since the code is pretty long.
#include<stdio.h>
#include <string.h>
#include<stdlib.h>
#include<math.h>
#include <mpi.h>
#include "mkl.h"
#define K(i,j) k[(i)+(j)*(n)]
void dgesv_( const MKL_INT* n, const MKL_INT* nrhs, double* a,
const MKL_INT* lda, MKL_INT* ipiv, double* b,
const MKL_INT* ldb, MKL_INT* info );
int main()
{
int *ipiv=malloc(n*sizeof(int));
for (i=0; i<n; i++) {
ipiv[i]=0;
}
for (globloop=0; globloop<=lasti; globloop++) {
double a[ndofs];
double rhs[ndofs];
double F[ndofs];
double *k=malloc(n*n*sizeof(double));
//var for stiffness matrix (this is the one acutally fed to dgesv)
//see define at top
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
K(i,j)=0.0;
}
}
//bunch of stuff modified, a,rhs,and F filled... ect
while (sos>=ep && nonlinloop<=maxit) {
double KFull[ndofs][ndofs];
for (i=0; i<ndofs; i++) {
for (j=0; j<ndofs; j++) {
KFull[i][j]=0.0;
}
}
//KFull filled with values..
//trim the arrays to account for bcs
double *b=malloc(n*sizeof(double));
for (i=0; i<n; i++) {
b[i]=rhs[i+2];
}
//k array filled
//see define above
for (i=0; i<n; i++) {
for (j=0; j<ndofs-2; j++) {
K(i,j)=KFull[i+2][j+2];
}
}
//SOLVER
dgesv_(&n,&one,k,&n,ipiv,b,&n,&info);
//now we must take our solution in b, and place back into rhs
for (i=0; i<n; i++) {
rhs[i+2]=b[i];
}
nonlinloop++;
free(b);
}
free(k);
}
free(ipiv);
return 0;
}
Freeing any one of these 3 variables gives me a segmentation fault. I am super-confused about this.

If n=ndofs-4 (as mentioned in the OP's comment) then ndofs-2 is greater then n. And then the code will be corrupting the memory at
K(i,j)=KFull[i+2][j+2];
because j runs up to ndofs-2-1 and K is (only) defined to be K[0..n-1][0..n-1].

Related

Access violation writting location error when calculating the transpose of a matrix

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.

problem with 2d array mallocation (segmentation fault)

I tried to malloc a 2d array, but it gdb gives me Segmentation fault in line 8. It seems like something is wrong with if (A[i+x][j+y]!=A[i][j].
By the way: This program should print out the dimensions of the maximum square-sized sub-matrix of an input matrix, such that all its digits are equal matrix, such that all its digits are equal.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int same_surrounding(int **A, int i, int j, int size){
for (int x=0; x<size; x++){
for (int y=0; y<size; y++){
if (A[i+x][j+y]!=A[i][j])
return 0;
}
}
return 1;
}
int main(){
int n, i, j, sub, max_sub;
int **A;
scanf("%d", &n);
A=malloc(sizeof*A*n);
for (i=0; i<n; i++){
A[i]=malloc(sizeof**A*n);
}
for (i=0; i<n; i++){
for (j=0; j<n; j++){
scanf("%d", &A[i][j]);
}
}
for (i=0; i<n; i++){
for (j=0; j<n; j++){
sub=1;
while (sub<n&&same_surrounding(A, i, j, sub)){
if (sub>max_sub)
max_sub=sub;
sub++;
}
}
}
printf("%d", max_sub);
for (i=0; i<n; i++){
free(A[i]);
}
free(A);
return 0;
}
There are mainly 2 things wrong with this code:
Your program is checking for submatrices beyond the dimension of input matrix n. for example, if n=5,i=3,j=0 and sub=3 you can easily see that your code is checking for numbers in A[i+x][j+y] i.e. upto A[5][2] which is out of bound of A. You need to check this before sending it to same_surrounding(). For that all you need to do is slightlt change the while loop:
while (sub<=n && i+sub<n && j+sub<n && same_surrounding(A, i, j, sub)){...}
Always initialize your variables. Here you didn't initialize max_sub variable. When you don't initialize your variables, it contains random garbage value. For example if the garbage value is 478231 and you are looking for largest square matrix of 5x5 matrix, you'll never reach the condition if (sub>max_sub) and as a result max_sub will never update. That's why always initialize your variable with a safe value, for example, max_sub=0.
Also, as a warning, you should use sizeof() instead of explicitly writing the number of bytes necessary for memory allocation. Because they might change depending on computer architecture.
A=(int**) malloc(sizeof(int*)*n);
for (i=0; i<n; i++){
A[i]=(int*)malloc(sizeof(int)*n);
}
Here's the working version of your code. All I did was some { } cleanup. If you have just one statement under for, while, if etc., you don't really need the braces.

C program to calculate determinants of matrixes with command line parameters

So I have task like this:
"Write a program that will calculate determinants of matrixes. Size of the matrix should be typed as a command line parameter of the program. The user should type the matrix elements from the keyboard once the program is executed. The determinants should be calculated for different square matrix sizes (<=3) and not for the single fixed one. Divide your program into several functions. Use pointers. The size of arrays you'll use is determined by user during the program execution, therefore there is no need to use dynamic memory allocation."
I've heard that it's not possible to do this task with command line parameters, but not dynamic memory allocation. I'm just a beginner, so I wouldn't know. I haven't gotten to the part with calculating the determinants, I only wrote the functions to input and print a matrix, but there are already problems. I'm really lost as to what should I do.
This is what I have so far (it is not compiling right):
void inputMatrix(int size);
void printMatrix(int *matrix, int size);
int main(int argc, char *argv[])
{
int size = atoi(argv[1]);
int *matrix;
inputMatrix(size);
printMatrix(*matrix, size);
return 0;
}
void inputMatrix(int size)
{
int i, j;
int *matrix;
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
scanf("%d", (*(matrix + i) + j));
}
}
}
void printMatrix(int *matrix, int size)
{
int i, j;
int *matrix;
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
printf("%d ", *(*(matrix +i) + j));
}
printf("\n");
}
}
The answer by Joni addresses the main issue, but there are other things to be fixed in OP's code.
For starters, we have to decide whether to use a an array of arrays (like int mat[3][3];) or a simple array (like int mat[9];), while in OP's code, there's some confusion about it:
int main(int argc, char *argv[])
{
// ...
int *matrix; // <-- This pointer is uninitialized, its value is indeterminated
// ...
printMatrix(*matrix, size);
// ^ dereferencing it, you are passing an 'int'
}
// ...
void printMatrix(int *matrix, int size)
{ // ^ a pointer to an int is expected
int i, j;
int *matrix; // <-- This is a local variable that will shadow the parameter
// with the same name and it is also uninitialized.
for(i=0; i<size; i++)
{
for(j=0; j<size; j++)
{
printf("%d ", *(*(matrix +i) + j));
// ^^^^ this is equivalent to 'matrix[i][j]',
// but 'matrix' is only a pointer to 'int'
}
printf("\n");
}
}
So, if any dynamic memory allocation must be avoided, we can write somthing like this:
// ...
#define MAX_SIZE 3
int main(int argc, char *argv[])
{
int matrix[MAX_SIZE][MAX_SIZE];
// read 'size' from command line arguments, then
inputMatrix(size, matrix); // <-- Note that I'm passing 'matrix' here too.
printMatrix(size, matrix);
// ...
}
// The functions must be modified accordingly, e.g.:
void printMatrix(int size, int matrix[][MAX_SIZE])
// The inner dimension must be specified ^^^^^^
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
printf("%d ", *(*(matrix + i) + j)); // <-- "Use pointers." they said
}
printf("\n");
}
}
In case you want to use a plain array instead, it can be written like this:
// ...
#define MAX_SIZE 9 // <-- the total size: 3*3
int main(int argc, char *argv[])
{
int matrix[MAX_SIZE];
// ...
printMatrix(size, matrix);
// ...
}
void printMatrix(int size, int matrix[])
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
printf("%d ", *(matrix + (i * size + j));
// Note the math ^^^^^^^^^^^^^^^^^
// In this simple case of row wise traversal, it could be as simple as
// *(matrix++)
}
printf("\n");
}
}
Since you're not allowed to use dynamic memory allocation, you'll have to create the matrix in the main function and pass it to the other functions as a parameter. This uses a feature of C called variable length arrays:
int matrix[size*size];
inputMatrix(size, matrix);
If variable length arrays are not allowed either, just make it matrix[9] - size is at most 3 in your assignment
Finding determinant of square matrix of order n (n is finite) is quite easy with dynamic memory allocation. But, what is important in this case, is to free the memory at the end of program.
You can view my code here!

Openmp segmentation fault when setting the number of threads through console

I have the code of matrices multiplication with using openmp:
#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main()
{
long int i, j, k;
//long int N = atoi(argv[1]);
double t1, t2;
double a[N][N],b[N][N],c[N][N];
for (i=0; i<N; i++)
for (j=0; j<N; j++)
a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
t1=omp_get_wtime();
#pragma omp parallel for shared(a, b, c) private(i, j, k)
for(i=0; i<N; i++){
for(j=0; j<N; j++){
c[i][j] = 0.0;
for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
}
}
t2=omp_get_wtime();
printf("Time=%lf\n", t2-t1);
}
Now I want to set the number of threads which I want through command line. I do that by using
atoi(argv[])
Namely
#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main(int argc, char** argv[])
{
long int i, j, k;
//long int N = atoi(argv[1]);
double t1, t2;
double a[N][N],b[N][N],c[N][N];
for (i=0; i<N; i++)
for (j=0; j<N; j++)
a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
int t = atoi(argv[1]);
t1=omp_get_wtime();
#pragma omp parallel for shared(a, b, c) private(i, j, k) num_threads(t)
for(i=0; i<N; i++){
for(j=0; j<N; j++){
c[i][j] = 0.0;
for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
}
}
t2=omp_get_wtime();
printf("Time=%lf\n", t2-t1);
}
Everything is fine, except one crucial thing: when I try to compute the product of matrices with dimension more than (more or less) 500, I get the mistake: "segmentation fault". Could someone clarify the reason for this mistake?
I don't know anything about openmp, but you are most assuredly blowing up your stack. Default stack space will vary from system to system, but with N == 1000, you are trying to put three 2D arrays totaling 3 million doubles on the stack. Assuming a double is 8 bytes, that's 24 million bytes, or just shy of 22.9MB. There can't be many systems allowing that kind of stack space. Instead, I'd recommend trying to grab that amount of memory from the heap. Something like this:
//double a[N][N],b[N][N],c[N][N];
double **a, **b, **c;
a = malloc(sizeof(double*) * N);
b = malloc(sizeof(double*) * N);
c = malloc(sizeof(double*) * N);
for (i=0; i<N; i++)
{
a[i] = malloc(sizeof(double) * N);
b[i] = malloc(sizeof(double) * N);
c[i] = malloc(sizeof(double) * N);
}
// do your calculations
for (i=0; i<N; i++)
{
free(a[i]);
free(b[i]);
free(c[i]);
}
free(a);
free(b);
free(c);
I've verified on my machine at least, that with N == 1000 I crash right out of the gate with EXC_BAD_ACCESS when trying to place those arrays on the stack. When I dynamically allocate the memory instead as shown above, I get no seg faults.

Segmentaion fault in C when doing matrix multiplication

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.

Resources