C - Segmentation Fault with dynamic allocations - c

I'm doing this program to find the saddle point of a matrix (elements there are the greatest number on their column and at the same time the smallest on their row)
So, here is the thing, I'm getting a Segmentation Fault. When using windows, it works fine actually, but when I'm going to run on Ubunto, it doesn't work. I, unfortunitely, only have windows on my machine, so I can't figure out why it is not working or where it is going wrong.
Could you guys help me out? Tell me what is wrong with the code, or where is the error please!
int main(){
int i, j, *ml, *mc, key = 1, z;
int ordem, **me;
char car;
/* ml = smallest of each row, mc = greatest of each column
* me = given matrix
* ordem = size of matrix */
scanf("%d", &ordem);
me = malloc(ordem * sizeof(int));
for(i = 0; i < ordem; i++){
me[i] = malloc(ordem * sizeof(int));
}
ml = malloc (ordem * sizeof(int));
mc = malloc (ordem * sizeof(int));
for(i = 0; i < ordem; i++){
scanf("%d", &me[i][0]);
for(j = 1; j < ordem; j++){
scanf(" %d", &me[i][j]);
}
do{
z = scanf("%c", &car);
}while ((z != EOF) && (car != '\n'));
}
If necessary, I can give you guys the rest of the code, but I'm quite sure that the error is happening in there, either on the malloc or the scanf.
Thanks a lot, really appreciate any help! Best regards!

int **me;
me = malloc(ordem * sizeof(int));
here is the mistake ! It's :
me = malloc(ordem * sizeof(int*));
Always double check your malloc, 90% of the segfault comme from here ...

Your issue is probably on the line
me = malloc(ordem * sizeof(int));
me is a int**, so you need to allocate for int*, not int.
This is giving you portability issues because different compilers do not necessarily use the same size for those data types. Try running this code on the different machines to test what is going on.
printf("The size of an int is %d\n", sizeof(int));
printf("The size of an int* is %d\n", sizeof(int*));
A way that you can modify your coding style so that this error is harder to make is to use the variable name in your sizeof like so
me = malloc(ordem * sizeof(*me));
This way you can visually see that you are allocating space for ordem variables of the type that me points to.

When you allocate the pointer array you need to take the element size of the pointer, not int. On your Ubuntu system the pointer size is probably 64 bit while ints are still 32, while on Windows both have the same size as was traditionally the case.

Related

What causes this difference in behaviour for malloc() and free() between Windows and Linux?

I am trying to dynamically allocate a 2D array the following way:
Have a pointer checker.
void chk (void* p) {
if (p == NULL) {
fprintf(stderr, "Couldn't allocate.\n");
exit (0);
}
}
Read the number of lines.
scanf("%d", &n);
Allocate the necessary memory for the array of arrays (v), and for the array that keeps the sizes of the lines (u).
v = (int**) calloc(n, sizeof(int));
chk(v);
u = (int*) calloc(n, sizeof(int));
chk(u);
For each line, read the number of elements in it (u[i]). Allocate the necessary memory for the current line (v[i]), and read the elements.
scanf("%d", &u[i]);
v[i] = (int*) calloc(u[i], sizeof(int));
chk(v[i]);
for (j = 0; j < u[i]; j++)
scanf("%d", &v[i][j]);
Print the values stored in u.
for (i = 0; i < n; i++)
printf("%d\n", u[i]);
Free the memory.
free(u);
for (i = 0; i < n; i++)
free(v[i]);
free(v);
This code runs correctly in Windows (with the free section uncommented), but fails to do so in Linux! Upon running the code in an online compiler (so under Linux), we could see two things:
u[0] is garbage, and u[1] is 0.
u[2], ..., u[n] are okay.
With the free section commented, 1. is possible. However, if free isn't commented, we would get the Abort signal from abort(3) (SIGABRT).
How are the last two points possible? What causes the difference between Windows and Linux? How can it be fixed?
Thank you!
This is a problem:
v = (int**) calloc(n, sizeof(int));
Is v supposed to be an array of int or int *? Your cast and sizeof operands don’t agree. The best way to fix this is to lose the cast and to use sizeof *v as your size:
v = calloc( n, sizeof *v );
Do the same for the allocations of u and each v[i] - the general idiom is
T *p = calloc( n, sizeof *p );
or
T *p;
...
p = calloc( n, sizeof *p );
Unless you are compiling this code as C++ or pre-C89, the cast on the return value of calloc is unnecessary and counterproductive.

c - Which is the correct way to dynamically allocate multidimensional float arrays? Valgrind error

I'm implementing a K-means algorithm in C. It works well most of the time, but debugging it with Valgrind tell me that I'm doing an "Invalid read of size 8 - Invalid write of size 8 - Invalid read of size 8" using '''memcpy''' at the beginning. I think the problem isn't there, but where I assign a value to the multidimensional float array element, which memory is dynamically allocated with '''malloc''' with a for loop at some point. 'Cause Valgrind also tell "Address 0x572c380 is 0 bytes after a block of size 80 alloc'd".
I've tried to add 1 to the number of bytes that I allocate, cause I thought that maybe '''malloc''' "needed" more memory to do its job, but nothing changed. I know maybe it's a basic error, but I'm quite new to the language and at my course it wasn't explain anything so "technical". I've tried to search the answer and explanation of the error but I have only found problems with '''char''' arrays, and with those I'd understood the function '''strcpy''' can resolve the issue. What about float arrays? It's the first time a use '''memcpy'''.
Here are pieces of code that raise those Valgrind messages.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
FILE* fp; //used to open a .txt file to read
char buf[100];
float ** a;
char * s;
int i;
int j;
int rows = 10;
fp = fopen("data.txt", "r");
if(fp==NULL){
perror("Error at open file.");
exit(1);
}
a = (float**) malloc(rows*sizeof(float*));
for(i=0; i<rows; i++){
s = fgets(buf, 100, fp); //reading .txt file
if (s==NULL){
break;
}
a[i] = malloc(dim*sizeof(float));
a[i][0] = atof(strtok(s, ","));
for(j=1; j<dim; j++){
a[i][j] = atof(strtok(NULL,",")); //save as float value the token read from a line in file, for example, from line "1.0,2.0,3.0" as first line -> get a[0][1] = 2.0
}
}
fclose(fp);
m = (float**) malloc(rows*sizeof(float*));
for (i=0; i<rows; i++){
m[i]=malloc(dim*sizeof(float)); //not initialized
}
memcpy(m, a, rows*dim*sizeof(float));
}
Can someone also help me understand why it works but Valgrind raises these error messages?
You're first allocating an array of float*, then allocating several arrays of float so your last memcpy(m, a, rows*dim*sizeof(float)) copies an array of float* (pointers to float) to another one, but using rows * dim floats, which #SomeProgrammerDude rightfully noted. That would copy pointers, and not values.
Also, as pointed by #xing, you're allocating rows but using righe (which you didn't show). It might be a cause of problems.
I would suggest allocating the whole array at once on the first row, then having all other rows pointing to adequate rows:
a = malloc(rows * sizeof(float*));
a[0] = malloc(dim * rows * sizeof(float)); // Allocate the whole matrix on row #0
for (i = 1; i < rows; i++) {
a[i] = a[0] + i * dim; // sizeof(float) automatically taken into account as float* pointer arithmetics
}
...
m = malloc(rows * sizeof(float*));
m[0] = malloc(dim * rows * sizeof(float));
memcpy(m[0], a[0], dim * rows * sizeof(float));
(add NULL checks of course)

Dynamic memory allocation repetition in C

I am somewhat new to C programming. I have a doubt regarding dynamic memory allocation. The following is a code in the main program for memory allocation.
double **mat=(double**)malloc(sizeof(double*)*n);
mat[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
mat[i] = mat[i-1] + n;
mat = create_square_matrix(n);
I want to call the function and create elements in the matrix inside the function. Do I have once again allocation memory inside the function like below or Is there any other method to avoid this tedious memory allocation repetition. Following is the function.
`double** create_square_matrix(int n)
{
int i,j,sum=0;
double **array2=(double**)malloc(sizeof(double*)*n);
array2[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
array2[i] = array2[i-1] + n;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
sum=sum+j;
array2[i][j]=sum;
}
}
return array2;
}
`
The above function returns the array which is stored in the 'mat' variable. And another question is how do I free the memory of variable 'array2' inside the function after using the return method. I can't free the memory possibly before returning the array. Is there a method to free the memory in the above function.
Your function create_square_matrix allocates memory and then fills it by some values.
Your top piece of code allocates memory, and then calls create_square_matrix which again allocates memory. It is like to mop floors before calling the janitor who also mops floors. You don't need to allocate memory twice. Not only it is unneccessary, in fact it is bad. Since you perform two allocations, the memory from the first one is lost, and there is no way to free it. This is called memory leak. Instead of
double **mat=(double**)malloc(sizeof(double*)*n);
mat[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
mat[i] = mat[i-1] + n;
mat = create_square_matrix(n);
you should write
double **mat = create_square_matrix(n);
As mentioned, in C there's no need to cast to/from void*. Also, your calloc is backwards: use N elements for the first argument, sizeof(element) for the second.
I will answer your question, and then suggest a better approach.
You are choosing double ** for your matrix. Even if it weren't square, you know exactly how many pointers and how many doubles you need, and of course how big each type is. So,
double **M = malloc( n * sizeof(double*) + n * m * sizeof(double) );
does the trick, does it not? If sizeof(double*) == sizeof(double) for your machine (probably true), then
double **M = calloc( (1+n) * m, sizeof(double) );
works, too, but less portably. You also get the zeros for free; you'll have trouble finding a machine for which it's not true that double f=0 yields a value for which all bits are zero.
But why define your matrix as an array of pointers? Why not instead define it as an array of doubles?
double *M = calloc( n * m, sizeof(double) );
Better yet, for the past 15 years or so, C has supported variable-length arrays, meaning you can define arrays whose size is determined at runtime. Back in K&R days, you could define an array M[n] unless n was a static constant or enum. If your arrays aren't ginormous -- meaning that for the machine in question they'll fit comfortably on the stack -- you can skip malloc and simply define your matrix by a size determined at runtime.
Even if you can't do that, can typedef one dimension dynamically,
typedef double (x_axis_t)[m];
double x_axis_t *M = calloc( n * sizeof(x_axis_t), sizeof(double) );
which is nice, because then you can access your array as
M[x][y];
Just don't try to use M[x,y], because that's something else altogether.
BTW, since you're new to the game, to use a c99 compiler, the standard command is c99, not cc. See your friendly manual for details. :-)
Using a nice function macro for memory allocation is always a good idea. Unless you have to free memory manually I would leave it to a garbage collector such as libgc. Below is an example. If you don't want to use a garbage collector you can just replace GC_MALLOC with malloc. When you free the array (manually) you must first free the individual rows.
#include <gc/gc.h>
#include <stdio.h>
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = GC_MALLOC((n) * sizeof (ptr)[0])
double **SquareMatrix(int n)
{
double **A;
int i, j;
NEW_ARRAY(A, n);
for (i = 0; i < n; i++) {
NEW_ARRAY(A[i], n);
for (j = 0; j < n; j++) {
A[i][j] = 0.0;
}
}
return A;
}
int main(void)
{
const int n = 5;
double **A;
int i, j;
A = SquareMatrix(n);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%5.2f ", A[i][j]);
}
putchar('\n');
}
return 0;
}

Dynamically allocated 2 dimensional array

I am trying to build two dimensional array by dynamically allocating. My question is that is it possible that its first dimension would take 100 values, then second dimension would take variable amount of values depending on my problem? If it is possible then how I would access it? How would I know the second dimension's boundary?
(See the comments in the code)
As a result you'll get an array such like the following:
// Create an array that will contain required variables of the required values
// which will help you to make each row of it's own lenght.
arrOfLengthOfRows[NUMBER_OF_ROWS] = {value_1, value_2, ..., value_theLast};
int **array;
array = malloc(N * sizeof(int *)); // `N` is the number of rows, as on the pic.
/*
if(array == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
// Here we make each row of it's own, individual length.
for(i = 0; i < N; i++) {
array[i] = malloc(arrOfLengthOfRows[i] * sizeof(int));
/*
if(array[i] == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
}
You can use array of 100 pointers:
int *arr[100];
then you can dynamically allocate memory to each of the 100 pointers separately of any size you want, however you have to remember how much memory (for each pointer) you have allocated, you cannot expect C compiler to remember it or tell it to you, i.e. sizeof will not work here.
To access any (allowed, within boundary) location you can simply use 2D array notation e.g. to access 5th location of memory allocated to 20th pointer you can use arr[20][5] or *(arr[20] + 5).
I believe the OP wants a single chunk of memory for the array, and is willing to fix one of the dimensions to get it. I frequently like to do this when coding in C as well.
We all used to be able to do double x[4][]; and the compiler would know what to do. But someone has apparently messed that up - maybe even for a good reason.
The following however still works and allows us to use large chunks of memory instead of having to do a lot of pointer management.
#include <stdio.h>
#include <stdlib.h>
// double x[4][];
struct foo {
double y[4];
} * x;
void
main(int ac, char * av[])
{
double * dp;
int max_x = 10;
int i;
x = calloc(max_x, sizeof(struct foo));
x[0].y[0] = 0.23;
x[0].y[1] = 0.45;
x[9].y[0] = 1.23;
x[9].y[1] = 1.45;
dp = x[9].y;
for (i = 0; i < 4; i++)
if (dp[i] > 0)
printf("%f\n", dp[i]);
}
The trick is to declare the fixed dimension in a struct. But keep in mind that the "first" dimension is the dynamic dimension and the "second" one is fixed. And this is the opposite of the old way ...
You will have to track the size of your dynamic dimension on your own - sizeof can't help you with that.
Using anonymous thingies you might even be able to git rid of 'y'.
Using a single pointer:
int *arr = (int *)malloc(r * c * sizeof(int));
/* how to access array elements */
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count; //count initialized as, int count=0;
Using pointer to a pointer:
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
In this case you can access array elements same as you access statically allocated array.

memcpy() with different data types

Trying to copy A into B....
char *A;
double *B;
unsigned int size = 1024;
A = malloc (size*size * sizeof (char));
B = malloc (size*size * sizeof (double));
//fill A here
memcpy (B, &A[0], (size*size * sizeof (char)));
Printing values in B don't match whats in A.
What's going wrong?
Thanks for any help!
Edit: The point of this is to test the memcpy function's speed in relation to the size of the L2 cache. I'm just wanting to make sure the code above is actually copying all of A into B. Sorry about leaving out this info: I just try to make it as simple as possible (and went too far this time)
It's hard to tell exactly what you are trying to do.
How are you printing values? Print routines like printf also depend on the type.
It sounds like you just want to get float input values. This can be done using the scanf family.
int num_floats = 10;
double* B = malloc (num_floats * sizeof (double));
int count;
for (count = 0; count < num_floats; count++)
{
printf("Insert float %d: ", count);
scanf("%f", &B[num_floats]);
}
for (count = 0; count < num_floats; count++)
{
printf("Float %d: %f", B[num_floats]);
}
free(B);
If you are trying to convert C-strings from char * to floating point numbers and don't want to use sscanf, you can also use atof.
const char* num_str = "1.01";
double num = atof(num_str);

Resources