Confusing Segmentation Fault When Reading From File - c

So, I'm trying to read a file of integers into 2 separate matrices. The first matrix is read in perfectly fine. Then the second one tries to read in from the file, gets to the last line and gets to a segfault. I have looked over the code about a bazillion times and can't figure out why I'm getting this segfault. Any help would be helpful!
Relevant code is pasted below:
int** allocation_matrix;
int** request_matrix;
allocation_matrix = (int **) malloc(num_processes * sizeof(int));
request_matrix = (int **) malloc(num_processes * sizeof(int));
for (i = 0; i < num_processes; i++)
{
allocation_matrix[i] = (int *) malloc(num_resources * sizeof(int));
request_matrix[i] = (int *) malloc(num_resources * sizeof(int));
}
for (i = 0; i < num_processes; i++)
{
for (j = 0; j < num_resources; j++)
{
fscanf(fp, "%d", &allocation_matrix[i][j]);
}
}
for (i = 0; i < num_processes; i++)
{
for (j = 0; j < num_resources; j++)
{
fscanf(fp, "%d", &request_matrix[i][j]);
printf("%d ", request_matrix[i][j]);
}
printf("\n");
}

num_processes * sizeof(int) is the wrong size as the wrong type was used.
Instead of trying to use the right type with the pointer, determine the size based on the de-referenced pointer. Easier to code right, review and maintain.
// allocation_matrix = (int **) malloc(num_processes * sizeof(int));
allocation_matrix = malloc(sizoef *allocation_matrix * num_processes);

Related

How to access a 2d array inside a struct using only pointers

Trying to understand pointers as a beginner in C-
I've got this struct:
typedef struct {
int size; // dimension of array
int **arr; // pointer to heap allocated array
} someStruct;
So I use malloc to generate this struct, and an array, and initialize all the values to zero-
someStruct *m = (someStruct*)malloc(sizeof(someStruct));
m->size = n;
m->arr = (int**)malloc(n * sizeof(int));
// initialize array
for (int i = 0; i < n; i++) {
*(m->arr + i) = (int*)malloc(n * sizeof(int));
// set value to 0
for (int j = 0; j < n; j++) {
*(*(m->arr + i) + j) = 0;
}
}
After this I basically continue to access the array in later stages using the same kind of pointer logic-
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int num = *(*(m->arr + i) + j);
printf("num: %d\n", num);
}
}
Here's the problem- when I try to use this method of access, I'm clearly not getting the right answer- my print output look like this:
num: -2043774080
num: 22031
num: 0
num: 0
...
num: 0
num: 0
Here's the really weird part- this seeming bug of the 'weird' random numbers only comes when I'm creating and accessing an array of size 5-
I've come to believe that the whole
*(*(m->arr + i) + j)
method of access must be wrong- any help on this would be really useful. Thanks in advance, I apologize if this was already answered, my searching was unable to find it.
You should give complete code, but I think I was able to figure out your intent. You have one glaring problem, and many style issues. Here is what I think your code should look like:
typedef struct {
int size; // dimension of array
int **arr; // pointer to heap allocated array
} MagicSquare;
:
:
// no need to dynamically allocate this, it is small
MagicSquare m;
m.size = n;
m.arr = malloc(n * sizeof(int*)); // note it is sizeof(int*), not (int)
// initialize array
for (int i = 0; i < n; i++) {
m.arr[i] = malloc(n * sizeof(int));
// set value to 0
for (int j = 0; j < n; j++) {
m.arr[i][j] = 0;
}
}
:
:
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("num: %d\n", m.arr[i][j]);
}
}
Note that if you want to initialize the allocated memory to zero, you should just use calloc, which does this initialization for you:
// initialize array
for (int i = 0; i < n; i++) {
m.arr[i] = calloc(n,sizeof(int));
}

How to correctly load data from a file in C

I'm new in C and I try to load data from a file to my program. My method worked for me in a similar task but not here and I don't know why. In my opinion, my code is logically correct.
Here is this part of code responsible for loading data and displaying it:
int q = fscanf(stale, "&d", &q); //number of lines, in the file it is a first line where this number is kept, and below it there a 5 lines with two columns of numbers
double* tab;
tab = (double*)malloc(q * 2 * sizeof(double)); //this is the array where data should be kept
for (int i = 0; i < q; i++)
{
for (int j = 0; j < 2; j++)
{
fscanf(stale, "%lf", &tab[i * q + j]);
}
}
for (int i = 0; i < q; i++)
{
for (int j = 0; j < 2; j++)
{
printf("%lf", tab[i * q + j]);
}
printf("\n");
}
What is wrong in my code?

C malloc (Segmentation fault: 11)

I'm trying to understand malloc but I keep getting "Segmentation fault: 11" with this piece of code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0, j = 0;
char ** ptr = (char **) malloc(sizeof(char*));
for(i = 0; i < 5; i++)
{
for(j = 0; j < 10; j++)
ptr[i][j] = 'a';
printf("%s\n", ptr[i]);
}
return 0;
}
I thought there wasn't enough bytes being allocated so I did malloc(sizeof(char*) * 100, but gives me the same error. What am I not understanding here?
When you allocate a 2D array, you need to allocate the individual sub-arrays as well. In addition, you need to say how many elements you wish to have. For that you multiply the desired count by the number of elements, like this:
char ** ptr = (char **) malloc(5*sizeof(char*));
// Size=5 ---------------------^
for(int i = 0; i < 5; i++) {
ptr[i] = malloc(11*sizeof(char));
// sizeof(char) is always 1, so the multiplication above is redundant.
// You need 11 elements for ten characters
for(int j = 0; j < 10; j++) {
ptr[i][j] = 'a';
}
// don't forget to null-terminate the string:
ptr[i][10] = '\0';
printf("%s\n", ptr[i]);
}
Your code is totally messed up in every aspect!
1) you allocated memory for exactly 1 Pointer to it. This means you can access ptr[0], but not ptr[1] ... ptr[4] as you are trying to do.
2) you never allocate anything for the elements in ptr[i].
3) you try to print a string a ptr[i] which is (even if your allocation would be right) never terminated.
4) although this is obviously only a beginners test, never forget to free your memory!!!!
To reach something CLOSE to what your sampel code is describing you could do:
int main()
{
int i,j;
char ** ptr = malloc( 5 * sizeof(char*) ); /* an array of 5 elements of type char* */
for(i = 0; i < 5; i++)
{
ptr[i] = malloc( 11*sizeof(char) ); /* The element i of the array is an array of 11 chars (10 for the 'a' character, one for the null-termination */
for(j = 0; j < 10; j++)
ptr[i][j] = 'a';
ptr[i][10] = '\0'; /* strings need to be null terminated */
printf("%s\n", ptr[i]);
}
// free your memory!
for (i=0; i<5; i++ )
{
free(ptr[i]);
}
free(ptr);
return 0;
Another way to allocate the memory is:
char (*ptr)[11] = malloc( sizeof(char[5][11]) );
for(i = 0; i < 5; i++)
{
for(j = 0; j < 10; j++)
ptr[i][j] = 'a';
ptr[i][10] = 0;
printf("%s\n", ptr[i]);
}
free(ptr);
It seems less hassle to use a single allocation than to use a lot of allocations, unless you have a pressing reason to do the latter.

C No memory available to program: unsafe to call malloc error

I am trying to create all of the matrices from size 10x10 to 1000x1000 around 980 I start running out of memory even though the program is clearly not using all 4GB of my system. My code looks like:
double **a3;
double **result;
a3 = malloc(k * sizeof(double *));
for(i = 0; i < k; i++)
{
a3[i] = malloc(sizeof(double));
}
result = malloc(k * sizeof(double *));
for(i = 0; i < k; i++)
{
result[i] = malloc(k * sizeof(double));
}
for(i = 0; i < k; i++)
{
for( j = 0; j < k; j++)
{
a3[i][j] = 0;
result[i][j] = 0;
}
}
...
for(i = 0; i < k; i++)
{
free(a3[i]);
free(result[i]);
}
free(a3);
free(result);
I am not sure why this doesn't work (it does work if I use int arrays but I need double arrays)
I am using Mac OSX 64bit
I'm not sure how 'clear' you actually are about not using all the memory that's available to your program. If I'm figuring rightly, you end up allocating a total of 333,833,185 doubles. At eight bytes each, that's over 2.5GB.
Not sure how much is available to your C compiler's memory management facilities... why not write a simple program that discovers what the biggest amount of memory you could malloc() is?

Allocating dynamic 2D char array

gcc 4.6.2 c89
Allocating memory for a 2D array and filling with characters.
However, I don't seem to be filling as when I print nothing is displayed.
Am I doing something wrong here?
char **attributes = NULL;
/* TODO: Check for memory being allocated */
attributes = malloc(3 * sizeof(char*));
int i = 0;
int k = 0;
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
sdp_attributes[i][k] = k;
}
}
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
printf("attributes[i][k] [ %c ]\n", attributes[i][k]);
}
}
Many thanks for any advice,
Two major issues:
First Issue:
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
You are reallocating sdp_attributes[i] at each iteration of the inner loop - thereby overwriting it each time. You probably wanted this instead:
for(i = 0; i < 3; i++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
for(k = 0; k < 5; k++) {
Second Issue:
sdp_attributes[i][k] = k;
You are basically writing the lower ascii characters. Most of them are not printable.
Something like this might do what you want:
sdp_attributes[i][k] = k + '0';
You probably want:
for (i = 0; i < 3; i++)
{
attributes[i] = malloc(5 * sizeof(char));
for (k = 0; k < 5; k++)
{
attributes[i][k] = k;
}
}
This ignores error checking on the allocation.
It also fixes the name of the array to match the declaration, but your code either wasn't compiling (don't post non-compiling code unless your question is about why it doesn't compile!) or you have another variable called sdp_attributes declared somewhere which you weren't showing us.
Your code was leaking a lot of memory. Each time around the k-loop, you allocated a new array of 5 characters and stored the pointer in attributes[i] (or sdp_attributes[i]), storing the new pointer over what was there before, so you overwrote the value of the first 4 pointers. You could not possibly free the first four items - they were lost irretrievably. Also, on the last iteration, you initialized the 5th element of the final array, but the previous 4 were not initialized and therefore contained indeterminate garbage.
Also, in your printing loop, the values in the array are control characters ^#, ^A, ^B, ^C and ^D; these do not necessarily print well with %c (especially not ^#, which is also known as NUL or '\0'). The printf() statement might be better written as:
printf("attributes[%d][%d] [ %d ]\n", i, k, attributes[i][k]);
This prints the array indexes (rather than simply the characters [i][k] for each entry), and prints the control characters as integers (since the char values are promoted to int when passed to printf()) rather than as control characters.
(It's also more conventional to use i and j for a pair of nested loops, and i, j, and k for triply nested loops, etc. However, that's a very minor issue.)
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
sdp_attributes[i][k] = k;
}
}
Your erasing the allocated memory every time you loop in the inner most loop.
Here is a correct version.
for(i = 0; i < 3; i++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
for(k = 0; k < 5; k++) {
sdp_attributes[i][k] = k;
}
}
And you should fix your declaration:
attributes = malloc(3 * sizeof(char*));
to
sdp_attributes = malloc(3 * sizeof(char*));
Don't forget to free up all the memory allocated
for(i = 0; i < 3; i++)
{
free(sdp_attributes[i]);
}
free(sdp_attributes);
The correct way to allocate and assign elements to 2d array is as follows (but this is a int array, you can try and change it for char array):
One thing to note: As mentioned by #Mysticial, you should add/subtract '0' to your int value to get the char value when using ASCII character set (remember our itoa() functions!).
#include <stdio.h>
#include <stdlib.h>
int main()
{
int row, column;
int **matrix;
int i, j, val;
printf("Enter rows: ");
scanf("%d", &row);
printf("Enter columns: ");
scanf("%d", &column);
matrix = (int **) malloc (sizeof(int *) * row);
for (i=0 ; i<row ; i++)
matrix[i] = (int *) malloc (sizeof(int) * column);
val=1;
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
matrix[i][j] = val++;
}
}
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
for (i=0 ; i<row ; i++)
free(matrix[i]);
free(matrix);
return 0;
}
Few points to note:
error handling should be added for malloc()
malloc()'ed memory must be free()'ed

Resources