I have to be losing my mind here. I'm getting a segfault at the line for(i = 0; i < N; i++) {. I've never encountered anything like this. Here's the full code:
#include <stdio.h>
#include <time.h>
#define N 2400
#define M 2000
#define P 500
int main() {
int a[N][N];
int b[N][N];
int c[N][N];
int i, j;
// Initialize matrix A
for(i = 0; i < N; i++) {
for(j = 0; j < M; j++) {
a[i][j] = j-1+2;
}
}
// Initialize matrix B
for(i = 0; i < M; i++) {
for(j = 0; j < P; j++) {
b[i][j] = i-j+1;
}
}
}
First : you have declared a, b and c as [N][N] matrix, but you initialize them as if they were [N][M] and [M][P] matrix. Considering N > M > P, that should not cause a segfault, but the intent is not clear.
Second, if you replace your defines by :
#define N 10
#define M 5
#define P 2
Your program work. This is because local variables a and b are stored on the stack and your stack is limited in size. Consult your compiler and your system documentation to know exactly the limits imposed.
To avoid such problem, allocate your memory using malloc or equivalent function, that allocate memory on the heap, which is less constrained.
Related
I'm working with Visual Studio C.
I found that the programs report errors in a strange way when I write outside the range of an allocated vector.
This first program:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1; // Wrong range!
printf("Hi!");
for (int k=0;k<1000;k++) \\ just to spend time!
for (int j = 0; j < 100000; j++)
sin(cos(j));
}
simply stops before "Hi!". This one:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
int* asd = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1;
printf("Hi!");
for (int k=0;k<1000;k++)
for (int j = 0; j < 100000; j++)
sin(cos(j));
}
ends without reporting any problem, although the difference is just that I allocated an extra array. And finally this:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
int* asd = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1;
printf("Hi!");
for (int k=0;k<1000;k++)
for (int j = 0; j < 100000; j++)
sin(cos(j));
free(qwe);
free(asd);
}
runs but, at the end (after the useless cycles), it gives me this message:
Of course, I know how to avoid the problem: just, pay attention to the index range. But my question is: what is exactly the meaning of the error message? What is the "normal block"? Why "after" and not "before"? What is exactly the displayed address? Why the message is issued only at the "free" command and not when the "heap corruption" takes place?
_NORMAL_BLOCK tells you what kind of allocation it was, there are also _CRT_BLOCK (internal to the library), _CLIENT_BLOCK (also allocated by user code but with some special handling available), and _FREE_BLOCK.
It's "after" and not "before" due to the order that corruption is check for. Since overruns are more likely than under that is checked for first.
The reason it waits until free is called is simply because it only checks during allocation and de-allocation calls. It would make programs run enormously slower if there were a system in place that checked every write to make sure it is in bounds.
I just started learning C and I wanted to try creating a test program that works with pointers, structures, and arrays, since I still have a hard time understanding them. I created this test file which is a distilled version of a larger project that I'm working on. The test file has a struct with a dynamic 2D array as a member of the struct:
typedef struct {
int ** array;
int rows, cols;
} Smaller;
However, after running the test file the terminal returns the following error:
zsh: segmentation fault ./a.out
I researched what this error means,
" Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.” " (Link)
But I'm still confused on how fix this problem. I'm pretty sure I allocated the correct amount of memory for each row and column. It's even more confusing because the terminal doesn't indicate which line the error is. I would appreciate any help on this issue.
Below is the full code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int ** array;
int rows, cols;
} Smaller;
void printArray (Smaller * s);
int main () {
int x, i, j;
Smaller * sand;
// allocate mem for number of rows
sand->array = malloc (3 * sizeof(int *));
//allocate mem for number of columns
sand->array = malloc(4 * sizeof(int));
sand->array = malloc(4 * sizeof(int));
sand->array = malloc(4 * sizeof(int));
// adding a constant value to the 2D array
for (i = 0; i < 3; i ++) {
for (j = 0; j < 4; j ++) {
sand->array[i][j] = 6;
}
}
printArray(sand);
return 0;
}
void printArray (Smaller * sand) {
printf("Welcome to the printArray function! \n");
int i, j;
for (i = 0; i < 3; i ++)
for(j = 0; j < 4; j ++)
printf("array[%d][%d] = %d \n", i, j, sand->array[i][j]);
}
The problem is, as #tromgy pointed out, you are overwriting the base sand->array with the column arrays instead of assigning them to it. A correct code would look like this:
#include <stdlib.h>
#define NUM_ROWS 3
#define NUM_COLS 4
typedef struct {
int ** array;
int rows;
int cols;
} Smaller;
void print_array(Smaller * s);
int main(void) {
Smaller * sand = malloc(sizeof(Smaller));
if (!sand) return -1; /* allocation failed, abort */
sand->rows = NUM_ROWS;
sand->array = malloc(sizeof(int*[NUM_ROWS]));
if (!sand->array) { /* allocation failed, abort */
free(sand); /* free sand first, though */
return -1;
}
for (size_t i = 0; i < NUM_ROWS; ++i) {
sand->array[i] = malloc(sizeof(int[NUM_COLS]));
if (!sand->array[i]) {
/* free the previous rows */
for (size_t j = 0; j < i; ++j) free(sand->array[j]);
free(sand->array);
free(sand);
return -1;
}
}
/* add a constant value to the array */
for (size_t i = 0; i < NUM_ROWS; ++i) {
for (size_t j = 0; j < NUM_COLS; j ++) {
sand->array[i][j] = 6;
}
}
print_array(sand);
/* Ok, now free everything */
for (size_t i = 0; i < NUM_COLS; ++i) {
free(sand->array[i]);
}
free(sand->array);
free(sand);
/* NOW we may exit */
return 0;
}
As you can see, allocating a structure like this is a lot of work, and you have to free whatever you allocate, so it's probably better to extract it out to a function, something like Smaller * smaller_init(size_t nrows, size_t ncols) and void smaller_destroy(Smaller * s) encapsulating all that work.
I will left an example below so you can compare it to the way you wrote it originally...
About your code:
Declare loop variables inside the for command
May be Smaller do not need to be a pointer
Keep dimensions as variables. It is more flexible
You did not set the values for rows and cols in the struct. And in main() do not use fixed values as 3 and 4 as you did
You should set all cells to different values, not the same. You will feel safer when you see reversible values, like 100*row + column in the example... This way you can see if the loops are ok and all elements are being printed. See this output for printArray():
0 1 2 3
100 101 102 103
200 201 202 203
Each line starts with the line number so you can test it a few times before going on.
make your program test itself. In printArray() for example show the dimensions like this:
printArray[3,4]
0 1 2 3
100 101 102 103
200 201 202 203
See the output of the example
always write the code to free the memory, in the reserve order of the allocation, maybe in a separate function that returns NULL in order to invalidate the pointer back in the calling code, like this
Smaller* freeArray(Smaller* A)
{
printf("\nfreeArray()\n");
for (int i = 0; i < A->rows; i++)
{
free(A->array[i]); // delete lines
printf("row %d free()\n", i);
}
free(A->array); // delete cols
printf("pointer to rows free()\n");
free(A); // delete struct
printf("struct free()\n");
return NULL;
}
This way you know that the pointer sand will not be left pointing to an area that has been free()d. Using such a pointer will crash your program so it may be good to write
sand = freeArray(sand);
output of the example code
printArray[3,4]
0 1 2 3
100 101 102 103
200 201 202 203
freeArray()
row 0 free()
row 1 free()
row 2 free()
pointer to rows free()
struct free()
Example code
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int** array;
int rows, cols;
} Smaller;
void fillArray(Smaller*);
Smaller* freeArray(Smaller*);
Smaller* makeArray(size_t, size_t);
void printArray(Smaller*);
int main(void)
{
int y = 3;
int x = 4;
// sand points to a Smaller
Smaller* sand = makeArray(y, x);
// adding known unique values to cells is easier
fillArray(sand);
printArray(sand); // show values
sand = freeArray(sand); // delete all
return 0;
}
void fillArray(Smaller* A)
{
for (int i = 0; i < A->rows; i++)
for (int j = 0; j < A->cols; j++)
A->array[i][j] = 100 * i + j;
}
Smaller* freeArray(Smaller* A)
{
printf("\nfreeArray()\n");
for (int i = 0; i < A->rows; i++)
{
free(A->array[i]); // delete lines
printf("row %d free()\n", i);
}
free(A->array); // delete cols
printf("pointer to rows free()\n");
free(A); // delete struct
printf("struct free()\n");
return NULL;
}
Smaller* makeArray(size_t y, size_t x)
{
// sand points to a Smaller
Smaller* sand = (Smaller*)malloc(sizeof(Smaller));
sand->rows = y;
sand->cols = x;
// allocate mem for number of rows, that is 'y'
sand->array = malloc(y * sizeof(int*));
// allocate mem for each of the 'x' columns
for (size_t i = 0; i < y; i++)
sand->array[i] = malloc(x * sizeof(int));
return sand;
};
void printArray(Smaller* sand)
{
printf("printArray[%d,%d]\n\n", sand->rows, sand->cols);
for (int i = 0; i < sand->rows; i++)
{
for (int j = 0; j < sand->cols; j++)
printf("%3d ", sand->array[i][j]);
printf("\n");
}
}
About the code
Please SO people do not bother pointing me not to cast the result of malloc(). It is by decision. This common recommendation is a reminiscence of the C-faq of the 90's and now we know that implicit conversions maybe not so good. In fact implicit things may cost you a lot of time: if you malloc() a series of different structs in a program and omit the types if some of them are for example reversed keep in mind that the use of all casts would help you avoid this costly type of mistake...
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX_STRING_SIZE 20
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int N, Q;
int i, j, k, l, m, x;
char **str;
scanf("%d\n", &N);
str = (char **)malloc(sizeof(char *) * N);
for(i = 0; i < N; i++){
str[i] = malloc(MAX_STRING_SIZE * sizeof(char));
scanf("%s",str[i]);
}
printf("%d\n",N);
for(j = 0; j < N; j++){
printf("%s",str[j]);
printf("\n");
}
scanf("%d",&Q);
printf("%d\n",Q);
char **qry_str;
qry_str = (char **)malloc(sizeof(char *) * Q);
for(l = 0; l < Q; l++){
qry_str = malloc(MAX_STRING_SIZE * sizeof(char));
scanf("%s",qry_str[l]);
}
for(m = 0; m < N; m++){
printf("%s",qry_str[m]);
printf("\n");
}
for(k = 0; k < N; k++)
free(str[k]);
free(str);
for(x = 0; x < N; x++)
free(qry_str[x]);
free(qry_str);
return 0;
}
I am new to programming, and I am trying to allocate memory for two 2d strings using malloc function, but when I try to input data for the second string qry_str, (null) appears on the screen, and the program exits.
My question is:
How do we dynamically allocate memory for 2D arrays in C multiple times?
Do I need to free the memory first before using it again? (Though when I try to do that it causes segmentation fault error.)
Is this the problem due to my compiler? (I am using gcc.)
In your second case, you're overwriting qry_str inside the loop, which is not what is intended. You most probably want
for(l = 0; l < Q; l++){
qry_str[l] = malloc(MAX_STRING_SIZE * sizeof(char));
scanf("%s",qry_str[l]);
}
That said, a few suggestion:
You don't need four separate counters i, j, l, m. The first clause of for statement re-assigns the counter to 0 anyway, even if you reuse only one.
sizeof(char) is gurantted to be 1 in C. Instead, you should consider writing the statements like
qry_str[l] = malloc(MAX_STRING_SIZE * sizeof *qry_str));
to make them more robust.
Always check for the return values for scanf() family to ensure success.
I'm writing a C for which I need to create a 2D array. I've found a solution to my problem using double pointers (pointers to pointers) in the following way:
#include <stdio.h>
#include <stdlib.h>
int d = 3;
#define DIM_MAX 9
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int **array = malloc(d*sizeof(int *));
for(int count = 0; count < d; count++)
{
array[count] = malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
The code above works pretty well (it seems), but I've read in the web that using pointer to pointer is not the correct way to create 2D arrays. So I've come up with the following code, which also works:
#include <stdio.h>
#include <stdlib.h>
#define DIM_MAX 9
int d = 3;
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int *array[DIM_MAX] = {0};
for(int count = 0; count < d; count++)
{
array[count] = (int *)malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
What is the difference in using any of the two ways above to write this code?
[Not an answer, but an alternative approach to achieve the desired result, namely defining a user-defined 2D array.]
Assuming the compiler in use supports VLAs you could do this:
#include <stddef.h> /* for size_t */
void init_a(size_t x, size_t y, int a[x][y]); /* Order matters here!
1st give the dimensions, then the array. */
{
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
a[i][j] = (int) (i * j); /* or whatever values you need ... */
}
}
}
int main(void)
{
size_t x, y;
/* Read in x and y from where ever ... */
{
int a[x][y]; /* Define array of user specified size. */
init_a(x, y, a); /* "Initialise" the array's elements. */
...
}
}
It is actually pretty simple. All you have to do is this:
int i[][];
You are overthinking it. Same as a normal array, but has two indexes.
Let's say you want to create a "table" of 4 x 4. You will need to malloc space for 4 pointers, first. Each of those index points will contain a pointer which references the location in memory where your [sub] array begins (in this case, let's say the first pointer points to the location in memory where your first of four arrays is). Now this array needs to be malloc for 4 "spaces" (in this case, let's assume of type INT). (so array[0] = the first array) If you wanted to set the values 1, 2, 3, 4 within that array, you'd be specifying array[0][0], array[0][1], array[0][2], array[0][3]. This would then be repeated for the other 3 arrays that create this table.
Hope this helps!
I want to reshape an array of length L to one of MxN, however rather than create new memory by copying the elements over in for loops I'd like to do some pointer casting to allow me to access the array with double subscripting (array[X][Y]) .
I've googled around for ages and couldn't find anything helpful.
Any help would really be appreciated.
EDIT: The array of interest is on the heap not stack.
Pointer casting doesn't seem like a good idea here. But if the number of columns is known before run-time, one option I often encounter is to simply define a macro e.g.
#define arrayName(i,j) arrayName[((i)*N) + (j)]
Or
#define ELEMENT(arrayName, i,j) (arrayName)[((i)*N) + (j)]
if you want it to be more flexible.
unions are your friends:
#include <stdio.h>
#define M 5
#define N 4
typedef union {
int a1[M * N];
int a2[M][N];
} U;
int main()
{
U u;
int i, j;
for (i = 0; i < M * N; ++i)
{
u.a1[i] = i;
}
for (i = 0; i < M; ++i)
{
for (j = 0; j < N; ++j)
{
printf("%8d", u.a2[i][j]);
}
printf("\n");
}
return 0;
}
typedefs are your friends:
#include <stdio.h>
#include <stdlib.h>
#define M 5
#define N 4
typedef int Array1D[M * N];
typedef int Array2D[M][N];
int main()
{
Array1D *a1 = malloc(sizeof(*a1));
Array2D *a2 = (Array2D *)a1;
int i, j;
for (i = 0; i < M * N; ++i)
{
(*a1)[i] = i;
}
for (i = 0; i < M; ++i)
{
for (j = 0; j < N; ++j)
{
printf("%8d", (*a2)[i][j]);
}
printf("\n");
}
free(a1);
return 0;
}
Note: above code has now been updated to use heap allocation so as not to break strict aliasing rules.
By the way if you want it super dynamic (as in no sizes are known at compile-time) you can do this by not copying all the values but by creating an index for the 2nd dimension like so:
#include <stdio.h>
#include <stdlib.h>
const int FULL = 100;
const int X = 10;
const int Y = 10;
int *dim1;
int **nested;
int main(void) {
dim1 = malloc(sizeof(int)*FULL);
nested = malloc(sizeof(int*)*X);
for(int i=0; i<X;i++)
{
nested[i] = &dim1[Y*i];
}
dim1[15] = 42;
printf("nested[1][5]: %d",nested[1][5]);
free(nested);
free(dim1);
return 0;
}