I am trying to have some kind of dynamically growing array/data structure in C. Below is the C code I have for it. But after it prints the array, it gives a run-time error as shown below in the snapshot. What is going wrong? It is being compiled using MS-Visual C++ 2010 (Free version) on a Windows-7.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a;
int i = 5;
if((a = (int *)malloc(i * sizeof(int))) == NULL) {
fprintf(stderr, "Error: failed malloc\n");
return 1;
}
for(i = 0; i < 5; i++)
a[i] = i;
printf("-- array after malloc\n");
for(i = 0; i < 5; i++)
printf(" a[%d] = %d\n", i, a[i]);
if((a = (int *)realloc(a, i * sizeof(int))) == NULL) {
fprintf(stderr, "Error: failed realloc\n");
return 1;
}
for(i = 0; i < 10; i++)
a[i] = i;
printf("\n-- array after realloc\n");
for(i = 0; i < 10; i++)
printf(" a[%d] = %d\n", i, a[i]);
free(a);
return 0;
}
//<important>
//weren't you supposed to do i = 10 here ????
//</important>
if((a = (int *)realloc(a, i * sizeof(int))) == NULL) {
fprintf(stderr, "Error: failed realloc\n");
return 1;
}
for(i = 0; i < 10; i++)
a[i] = i;
I think this was supposed to resize array to 10 and use it, but you never changed i to 10 so i is still 5 and you go out of range
On this line:
if((a = (int *)realloc(a, i * sizeof(int))) == NULL) {
i still contains the value 5. So basically you are realloc'ing for 5 integers while you assign 10 integers in the next loop: an error.
This would be the fixed code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a;
int i;
if((a = (int *)malloc(5 * sizeof(int))) == NULL) {
fprintf(stderr, "Error: failed malloc\n");
return 1;
}
for(i = 0; i < 5; i++)
a[i] = i;
printf("-- array after malloc\n");
for(i = 0; i < 5; i++)
printf(" a[%d] = %d\n", i, a[i]);
if((a = (int *)realloc(a, 10 * sizeof(int))) == NULL) {
fprintf(stderr, "Error: failed realloc\n");
return 1;
}
for(i = 0; i < 10; i++)
a[i] = i;
printf("\n-- array after realloc\n");
for(i = 0; i < 10; i++)
printf(" a[%d] = %d\n", i, a[i]);
free(a);
return 0;
}
Related
In visual studio 2022 I can't compile this little program and on Clion, visual studio code and others it compiles.
I don't know if it could be a problem of the clang compiler or some configuration of visual studio (but stills on default).
#include <stdio.h>
int main() {
//Variable declarations
int size;
printf("INPUT\n");
printf("SIZE (2-3)?\n");
scanf("%d", &size);
int t[size][size]; //This is marked as wrong (only in visual studio 2022 not other IDE's)
int i = 0;
int j = 0;
//matrix read
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
printf("POSITION(%d, %d)?\n", i, j);
scanf("%d", &t[i][j]);
}
}
int calc = 0;
//calc matrix
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
calc = calc + t[i][j];
}
}
printf("suma: %d", calc);
return 0;
}
Thanks for reading.
I've tested the code on other IDE's and compiles without problems.
Instead of a Variable Length Array, a pointer to pointer, int **t, could be used.
Allocate the pointers and then for each pointer, allocate the elements.
#include <stdio.h>
#include <stdlib.h>
int main() {
//Variable declarations
int size;
printf("INPUT\n");
printf("SIZE (2-3)?\n");
if ( 1 != scanf("%d", &size)) {
fprintf ( stderr, "Could not scan an integer\n");
return 1;
}
int **t = NULL; // pointer to pointer
if ( NULL == ( t = malloc ( size * sizeof *t))) {
fprintf ( stderr, "Could not allocate pointers\n");
return 1;
}
int each = 0;
for ( each = 0; each < size; ++each) {
if ( NULL == ( t[each] = malloc ( size * sizeof **t))) {
fprintf ( stderr, "Could not allocate elements\n");
return 1;
}
}
int i = 0;
int j = 0;
//matrix read
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
printf("POSITION(%d, %d)?\n", i, j);
if ( 1 != scanf("%d", &t[i][j])) {
fprintf ( stderr, "Could not scan an integer\n");
return 1;
}
}
}
int calc = 0;
//calc matrix
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
calc = calc + t[i][j];
}
}
printf("suma: %d\n", calc);
for (i = 0; i < size; i++) {
free ( t[i]);
}
free ( t);
return 0;
}
Below is a solution to the codewars training.
https://www.codewars.com/kata/59f4a0acbee84576800000af/train/c
Test Crashed
Caught unexpected signal: SIGSEGV (11). Invalid memory access.
I get an error message like this, what's wrong?
I think it's probably part of the strtok function, but please tell me what's wrong.
#include <stdlib.h>
#include <string.h>
double pos_average(char *s, unsigned n)
{
char **matrix;
char *p;
unsigned int i, j, k;
unsigned int subst_len = ( strchr(s,',') - s ) / sizeof(char);
double count = 0;
matrix = (char**)calloc( n + 1 ,sizeof(char*) );
if(!matrix) exit(0);
for(i = 0; i < n; i++)
{
matrix[i] = (char*)calloc( subst_len + 1 ,sizeof(char) );
if(!matrix[i]) exit(0);
}
for(i = 0; i < n; i++)
{
if(i == 0){
p = strtok(s, " ");
strncpy(matrix[i], p, subst_len);
}
else{
p = strtok(NULL," ");
strncpy(matrix[i], p, subst_len);
}
}
for(i = 0; i < n - 1; i++)
{
for(j = i + 1; j < n; j++)
{
for(k = 0; k < subst_len; k++)
{
if(matrix[i][k] == matrix[j][k]) count++;
}
}
}
for(i = 0; i < n; i++) free(matrix[i]);
free(matrix);
return (count / ( ( (double)n * ( (double)n - 1.0 ) ) / 2.0 ) ) * 100.0;
}
Basically, the input file should look like this:
4
1 2 3 4
2 1 4 3
4 3 2 1
3 4 1 2
Where the first line is the size of the square matrix. However, I can't properly load the input directly into n and then into the matrix. I avoided such problem by creating a "loader" array.
int n, loader[100], p=0;
while(feof(data) == 0) {
if(p == 0) {
fscanf(data, "%d", &n); //taking n
p++;
} else {
fscanf(data, "%d", &loader[p]); //taking matrix values for p>0
p++;
}
}
//loading the matrix
int mat[n][n], o = 1; //o is set to 1, as the loader
//has been loaded from position 1.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
printf("%d\n", loader[o]);
mat[i][j] = loader[o];
o++;
}
}
However, I think it is just unnecessary and there might be a faster way to directly take the matrix size and its values. When I programmed in such way, I received a welcoming Segmentation Fault error.
This code seems to work:
int loadMatrix(char *pth)
{
int i, j, n, **mat, p = 0, num;
FILE *fd;
fd = fopen(pth, "r");
if(fd == NULL) return(-1);
/* Read matrix size */
if(fscanf(fd, "%d", &n) == EOF) return(-1);
printf("Size: %d\n", n);
mat = malloc(n * sizeof(int *));
for(i = 0; i < n; i++) mat[i] = malloc(sizeof(int) * n);
while(fscanf(fd, "%d", &num) != EOF && p < (n * n)) {
mat[p / n][p % n] = num;
p++;
}
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
for(i = 0; i < n; i++) free(mat[i]);
free(mat);
fclose(fd);
return(0);
}
Hey I got this error and I tried like 10 solutions and neither works. I want to load 2 matrix, each one from its own txt file then to multiply them. I can't compile cause of LNK1120 and LNK2019 errors.
Here is my code:
int main(int argc, char *argv[])
{
FILE *macierz1, *macierz2, *fw;
char *line = malloc(1000);
int count = 0;
macierz1 = fopen("macierz1.txt", "r");
if (macierz1 == NULL) {``
printf("nie można otworzyć", argv[1]);
exit(1);
}
macierz2 = fopen("macierz2.txt", "r");
if (macierz2 == NULL) {
printf("nie można otworzyć", argv[2]);
exit(1);
}
double *data = (double*)malloc(1000 * sizeof(double));
if (data == NULL)
{
printf("błąd lokowania pamięci");
return EXIT_FAILURE;
}
getline(&line, &count, macierz1);
int read = -1, cur = 0, columCount1 = 0;
while (sscanf(line + cur, "%lf%n", &data[columCount1], &read) == 1)
{
cur += read; columCount1++;
}
int rowCount1 = 1;
while (getline(&line, &count, macierz1) != -1) { rowCount1++; }
printf("%d\n", columCount1);
printf("%d\n", rowCount1);
getline(&line, &count, macierz2);
read = -1, cur = 0;
int columCount2 = 0;
while (sscanf(line + cur, "%lf%n", &data[columCount2], &read) == 1)
{
cur += read; columCount2++;
}
int rowCount2 = 1;
while (getline(&line, &count, macierz2) != -1) { rowCount2++; }
printf("%d\n", columCount2);
printf("%d\n", rowCount2);
int i = 0;
int j = 0;
int **mat1 = (int **)malloc(rowCount1 * sizeof(int*));
for (i = 0; i < rowCount1; i++)
mat1[i] = (int *)malloc(columCount1 * sizeof(int));
fseek(macierz1, 0, SEEK_SET);
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount1; j++)
fscanf(macierz1, "%d", &mat1[i][j]);
}
i = 0;
j = 0;
printf("\n\n");
//print matrix 1
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount1; j++)
printf("%d", mat1[i][j]);
printf("\n");
}
i = 0;
j = 0;
int **mat2 = (int **)malloc(rowCount2 * sizeof(int*));
for (i = 0; i < rowCount2; i++)
mat2[i] = (int *)malloc(columCount2 * sizeof(int));
fseek(macierz2, 0, SEEK_SET);
for (i = 0; i < rowCount2; i++)
{
for (j = 0; j < columCount2; j++)
fscanf(macierz2, "%d", &mat2[i][j]);
}
i = 0;
j = 0;
printf("\n\n");
//print matrix 2
for (i = 0; i < rowCount2; i++)
{
for (j = 0; j < columCount2; j++)
printf("%d", mat2[i][j]);
printf("\n");
}
i = 0;
int **mat3 = (int **)malloc(rowCount1 * sizeof(int*));
for (i = 0; i < rowCount1; i++)
mat3[i] = (int *)malloc(columCount2 * sizeof(int));
i = 0;
j = 0;
int k = 0;
int sum = 0;
if (columCount1 != rowCount2)
{
puts("The number of columns in Matrix 1 is not same as the number of rows in Matrix 2");
exit(1);
}
//multiplication of two matrices
for (i = 0; i<rowCount1; i++)
{
for (j = 0; j<columCount2; j++)
{
mat3[i][j] = 0;
for (k = 0; k<columCount1; k++)
{
mat3[i][j] = mat3[i][j] + mat1[i][k] * mat2[k][j];
}
}
}
//print multiplication result
printf("\n\nResult = \n\n");
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount2; j++)
printf("%d", mat3[i][j]);
printf("\n");
}
for (i = 0; i< rowCount1; i++)
free(mat1[i]);
free(mat1);
for (i = 0; i< rowCount2; i++)
free(mat2[i]);
free(mat2);
for (i = 0; i< rowCount1; i++)
free(mat3[i]);
free(mat3);
free(data);
return 0;
}
Since you're using Visual C++, there is no such C function as getline. The C compiler that comes with Visual C++ adheres to the C89 specification.
Use fgets to retrieve the data from the file.
If you really want to use getline in your Visual C++ (really C) program, you could try this code from GNU that implements the function.
There is a stray '`' in program posted at the end of the line:
if (macierz1 == NULL) {``
and
getline
function is not defined.
add needed includes:
#include <stdio.h>
#include <stdlib.h>
I am working on a Matrix Multiplication problem and I am dynamically allocating arrays
Here is what I currently have:
global:
int **a;
in my allocatematrix function: (m - row, k - col)
a = (int **)malloc(m * sizeof(int *));
for (i=0; i<m; i++)
{
a[i] = (int *)malloc(k * sizeof(int));
}
// Note that arr[i][j] is same as *(*(arr+i)+j)
// just to test my array allocation is working
for (i = 0; i < m; i++)
{
for (j = 0; j < k; j++)
{
a[i][j] = ++count; // OR *(*(arr+i)+j) = ++count
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < k; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
// I would like to pass my pointer to pointer
// into a subroutine, such that it transforms the
// the global double array, but it keeps blowing up here
loadMatrix(fp, &a, m, k);
load matrix function:
// read in the file
void loadMatrix(FILE *fp, int ***arr, int size1, int size2)
{
//fp = fopen(name, "r");
if (fp == NULL)
{
printf("Error while opening file!\n");
exit(0);
}
int i, j;
for(i = 0; i < size1; i++)
{
for(j = 0; j < size2; j++)
{
int value = 0;
fscanf(fp, "%d", &value);
printf("Current Value: %d\n", value);
//value = (((arr + i)) + j);
// line below is where I think I have the issue
*(*(*(arr+i)+j)) = value;
}
}
}
sample run: with this line commented ((*(arr+i)+j)) = value;
3 2 3
1 2
3 4
5 6
Current Value: 1
Current Value: 4
Current Value: 2
Current Value: 5
Current Value: 3
Current Value: 6
with out commented out:
3 2 3
1 2
3 4
5 6
Current Value: 1
Current Value: 4
Current Value: 2
Segmentation fault (core dumped)
You don't need a int *** pointer, if you are passing a pointer, the data it points to will be modified by the function, what you can do is this
// read in the file
void loadMatrix(FILE *fp, int **arr, int size1, int size2)
{
if (arr == NULL)
return;
if (fp == NULL)
{
printf("Error while opening file!\n");
exit(0);
}
int i, j;
for (i = 0 ; i < size1 ; i++)
{
for (j = 0 ; j < size2 ; j++)
{
int value = 0;
/* test that fscanf() succeeded reading an integer */
if (fscanf(fp, "%d", &arr[i][j]) != 1)
arr[i][j] = 0; /* this just prevents that arr[i][j] be uninitialized */
}
}
}
Where you say you test your allocation is working, that doesn't test anything, the only test you can performa is the return value from malloc(), if the allocation fails it returns NULL, so testing that your allocation worked is done like this
a = malloc(m * sizeof(int *));
if (a == NULL)
pleaseDoSomethingAboutIt_AllocationFailed_DoNotContinue();
for (i = 0 ; i < m ; i++)
{
a[i] = malloc(k * sizeof(int));
if (a[i] == NULL)
{
while (--i)
free(a[i]);
free(a);
pleaseDoSomethingAboutIt_AllocationFailed_DoNotContinue();
}
}
If the allocation fails, and you still dereference the pointer, like in your test, you will invoke undefined behavior, and hence you can't test for anything, because you can't know what is going to happen.