Trying to create a map for a little game. When initialising the map with 2D arrays using malloc, the main function will run okay when the printMap function is commented out, however when trying to display the map with printMap, it returns a Segmentation fault. Totally lost at why this isn't working. Any help appreciated.
This is work for University, who insist the code is in C89 and I compile with -ansi -pedantic -Wall -Werror.
GAME.C file
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"random.h"
void createMap(char*** map, int xCoord, int yCoord) {
int i, j;
xCoord += 2;
yCoord += 2;
char** mapArray;
mapArray = (char**)malloc(yCoord * sizeof(char*));
for (i = 0; i < yCoord; i++) {
mapArray[i] = (char*)malloc(xCoord * sizeof(char));
}
for (i = 0; i < yCoord; i++) {
for (j = 0; j < xCoord; j++) {
mapArray[i][j] = "0";
}
}
*map = mapArray;
}
void printMap(char** map, int xCoord, int yCoord) {
xCoord += 2;
yCoord += 2;
printf("%d, %d", xCoord, yCoord);
int i, j;
for (i = 0; i < yCoord; i++) {
for (j = 0; j < xCoord; i++) {
printf("%d %d", i, j);
printf("%c", map[i][j]);
}
printf("\n");
}
}
MAIN.C file
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include "random.h"
#include "game.h"
int main(void) {
int xCoord = 5;
int yCoord = 5;
char** map;
createMap(&map, xCoord, yCoord);
printMap(map, xCoord, yCoord);
return 0;
}
The function createMap is incorrectly initializing objects of the type char with pointers of the type char * to which the string literal "0" is implicitly converted in these for loops
for (i = 0; i < yCoord; i++) {
for (j = 0; j < xCoord; j++) {
mapArray[i][j] = "0";
}
}
Instead of the string literal you need to use integer character constant '0' as for example
for (i = 0; i < yCoord; i++) {
for (j = 0; j < xCoord; j++) {
mapArray[i][j] = '0';
}
}
Another problem is a typo in this loop within the function printMap
for (j = 0; j < xCoord; i++) {
^^^^
You need to write
for (j = 0; j < xCoord; j++) {
^^^^
Related
#define N 3
int subMatrix(int a[][N]) {
int i, j;
int sum = 0;
int arr[N];
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
return *arr;
}
void main() {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
for (int i = 0; i < N; i++) {
printf("%5d", subMatrix(a[i]));
}
}
The function works fine, the problem is when I'm returning the new array and loop over it in the main function I get the first element of the array and the other elements are addresses.
i did it before with another array with size of doubles and it worked.
There is something i miss?
double avgMatrix(int a[][C]) {
int i, j, sum=0;
double M[R];
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
sum += a[i][j];
}
M[i] = (double)sum / C;
sum = 0;
}
return *M;
}
void main() {
int a[R][C] = {
{9,2,4},
{3,8,11},
{3,1,2}
};
for (int i = 0; i < R; i++)
printf("%5.2lf", avgMatrix(a[i]));
}
this code works. what can be the difference?
I do not really understand what your function subMatrix does.
Your code needs a few modifications to be able to compile.
First, include the necessary header #include <stdio.h>, because your code needs printf.
Second, make sure the passed parameter and the attribute be the same type.
Third, if you would like to return an array from a function, you should use dynamic allocation function to help you do that. malloc
/* At least, make sure to include necessary head files
* #include <stdio.h>
*/
#define N 3
int subMatrix(int a[][N]) {
int i, j;
int sum = 0;
int arr[N];
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
/* Because the passed parameter is one dimensional
* so the following code does not make sense.
*/
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
/* arr is a local variable. It is actually a pointer
* It should never be returned.
* In fact, *arr is only the first element of the array of arr.
* At least, you should return the address of the first element.
* Considering your purpose, to use dynamic allocation is proper.
*/
return *arr;
}
/* 'void main()' is not right.
* 'int main(void)' is the right way.
*/
void main() {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
for (int i = 0; i < N; i++) {
/* a[i] is a one-dimensional array,
* but subMatrix needs a two dimensional one.
*/
printf("%5d", subMatrix(a[i]));
}
}
A possible working code:
#include <stdio.h>
#include <stdlib.h>
#define N 3
int *subMatrix(int a[N][N]) {
int sum = 0;
int *arr = (int *)malloc(N*sizeof(int));
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
sum += a[i][j];
sum -= a[j][i];
}
arr[i] = sum;
sum = 0;
}
return arr;
}
int main(void) {
int a[N][N] = {
{9,2,4},
{3,7,11},
{3,1,2}
};
int *arr = subMatrix(a);
for (int i = 0; i < N; i++)
printf("arr[%d] : %d\n", i, arr[i]);
free(arr);
}
Is this what you want? Try it.
Given two arrays: int nums[N] and int *ptrs[N] (N is a constant number).
I have to initialize the first array with some numbers. After that, i have to initialize the second array, so every element of the second array points to the element with the same index of the first array. (ptrs[0] points to nums[0],...).
Now i have to write a function with "ptrs" as argument that modifies the pointers in such a way that the first element of the second array points to the smallest number in the first array,..)
It's not allowed to change the "nums-array", i can only change the "ptrs-array".
This is my code i already have, but when i run it, the "nums-array" changes too.
What do i do wrong?
#include <stdio.h>
#define N 6
void sort(int *ptrs);
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int(*ptrs)[N];
int i;
ptrs = nums;
sort(ptrs);
for (i = 0; i < N; i++)
printf("nummer is: %d en %d\n", (*ptrs)[i], nums[i]);
return 0;
}
void sort(int *ptrs)
{
int i, j, tmp;
for (i = 0; i < N; i++)
for (j = i + 1; j < N; j++)
if ((ptrs)[i] > (ptrs)[j])
{
tmp = (ptrs)[i];
(ptrs)[i] = (ptrs)[j];
(ptrs)[j] = tmp;
}
}
Fix for the first part:
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int *ptrs[N]; // fix
int i;
for(i = 0; i < N; i++) // fix
ptr[i] = nums+i; // fix (or ptr[i] = &nums[i])
I found the solution, thanks for helping guys!
#include <stdio.h>
#define N 6
void sort(int ptrs[], int nums[]);
int main()
{
int nums[N] = { 1,6,7,8,2,5 };
int i,j,*p, *ptrs[N];
for (i = 0; i < N; i++) {
ptrs[i] = &nums[i];
}
sort(ptrs, nums);
return 0;
}
void sort(int *ptrs[], int nums[])
{
int i, j, tmp, p[N];
for (i = 0; i < N; i++)
p[i] = *ptrs[i];
for(j = 0; j < N; j++)
for (i = 0; i <= N; i++)
if (p[i] > p[i+1])
{
tmp = (ptrs)[i];
(ptrs)[i] = (ptrs)[i+1];
(ptrs)[i+1] = tmp;
for (i = 0; i < N; i++)
p[i] = *ptrs[i];
}
for (i = 0; i < N; i++)
printf("nummer is: %d en %d\n", *ptrs[i], nums[i]);
return;
}
The title is pretty clear I think.
I am trying to create a program that calculates a 3x3 linear system using determinants, but I am getting a segmentation fault. Here is the code:
#include<stdio.h>
int determinant(int n, int m, int det[m][n])
{
int res;
res = det[0][0]*det[1][1] - det[0][1]*det[1][0];
return res;
}
int main(void)
{
int arr[3][4], det[2][2], i, j, D; //Dx1, Dx2, Dx3
for(i = 0; i < 3; i++)
{
printf("Eisagete tous suntelestes ths %dhs eksisoshs.", i+1);
scanf("%d %d %d %d", &arr[i][0], &arr[i][1], &arr[i][2], &arr[i][3]);
}
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+1];
}
}
D = arr[0][0]*determinant(2, 2, det);
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+((j == 1) ? 1 : 0)];
}
}
D -= arr[0][1]*determinant(2, 2, det);
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j];
}
}
D += arr[0][2]*determinant(2, 2, det);
printf("%d\n", D);
}
I am getting the error right after completing the first for loop in main.
In the block:
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+1];
}
}
You increment i in both loops, and adding 1 more to it while reading from the array. So at arr[i+1] you are reading to far.
A segmentation fault basically means you are trying to read something you don't have access to.
You shoud never do what you're doing by passing static array sizes m and n as function argument:
int determinant(int n, int m, int det[m][n])
Check https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html for info
I've been working on this for days but can't seem to make it work out.
Sorry in advance for the unholy length of this, so if anyone takes the time to go through it and try to understand this mess, I'd owe you.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct cart {
int id;
char *nume;
} cart;
typedef struct pach {
int id, idCartier, strada, numar, prioritate, codificare;
float greutate;
char* mesaj;
int adresa[18];
} pach;
typedef struct post {
int id, nrPachete;
int vector[50];
} post;
int citeste(int *nrP, cart *cartier, pach *pachet, int *nrC) {
printf("Punctul 1\n");
int i, j;
scanf("%d", nrC);
for (i = 0; i < *nrC; i++) {
cartier[i].id = i;
char aux[500];
scanf("%s", aux);
cartier[i].nume = malloc(strlen(aux) + 1);
cartier[i].nume = aux;
printf("%d %s\n", cartier[i].id, cartier[i].nume);
}
scanf("%d", nrP);
for (i = 0; i < *nrP; i++) {
pachet[i].id = i;
char aux[500];
for (j = 0; j < 18; j++)
scanf("%d", &pachet[i].adresa[j]);
scanf("%d %f", &pachet[i].prioritate, &pachet[i].greutate);
getchar();
fgets(aux, 256, stdin);
pachet[i].mesaj = malloc(strlen(aux) + 1);
pachet[i].mesaj = aux;
printf("%d\n", pachet[i].id);
for (j = 0; j < 18; j++)
printf("%d ", pachet[i].adresa[j]);
printf("\n%d %.6f ", pachet[i].prioritate, pachet[i].greutate);
printf("%s", pachet[i].mesaj);
}
return *nrP;
}
void extrage(int *nrP, pach *pachet) {
printf("\nPunctul 2\n");
int i, j;
for (i = 0; i < *nrP; i++) {
pachet[i].idCartier = 0;
pachet[i].strada = 0;
pachet[i].numar = 0;
for (j = 0; j < 5; j++)
pachet[i].idCartier += pachet[i].adresa[j] * pow(2, (4 - j));
for (j = 5; j < 10; j++)
pachet[i].strada += pachet[i].adresa[j] * pow(2, (9 - j));
for (j = 10; j < 18; j++)
pachet[i].numar += pachet[i].adresa[j] * pow(2, (17 - j));
printf("%d %d ", pachet[i].id, pachet[i].idCartier);
printf("%d %d\n", pachet[i].strada, pachet[i].numar);
}
}
void distribuie(int *nrP, pach *pachet, post *postas, int *nrC, cart *cartier) {
printf("Punctul 3\n");
int i, j;
for (i = 0; i < *nrC; i++) { // FOR-1A
postas[i].nrPachete = 0;
postas[i].id = i;
for (j = 0; j < 50; j++)
postas[i].vector[j] = 0;
}
for (i = 0; i < *nrC; i++) { // FOR-1B
for (j = 0; j < *nrP; j++) {
if (cartier[i].id == pachet[j].idCartier) {
postas[i].vector[postas[i].nrPachete] = pachet[j].id;
postas[i].nrPachete++;
}
}
printf("%d %d ", postas[i].id, postas[i].nrPachete);
for (j = 0; j < postas[i].nrPachete; j++)
printf("%d ", postas[i].vector[j]);
printf("\n");
}
}
void ordoneaza(pach *pachet, int *nrC, post *postas) {
printf("Punctul 4\n");
pach aux;
int i, j, k = 0, schimbat = 1;
for (i = 0; i < *nrC; i++) {
while (schimbat) {
schimbat = 0;
for (j = 0; j < postas[i].nrPachete - k; j++)
if (pachet[postas[i].vector[j]].prioritate < pachet[postas[i].vector[j+1]].prioritate) {
aux = pachet[postas[i].vector[j]];
pachet[postas[i].vector[j]] = pachet[postas[i].vector[j+1]];
pachet[postas[i].vector[j+1]] = aux;
schimbat = 1;
}
k++;
}
k = 0;
schimbat = 1;
for (j = 0; j < postas[i].nrPachete; j++) {
for (k = j; k < postas[i].nrPachete; k++) {
if (pachet[postas[i].vector[j]].prioritate == pachet[postas[i].vector[k]].prioritate)
if (pachet[postas[i].vector[j]].greutate < pachet[postas[i].vector[k]].greutate) {
aux = pachet[postas[i].vector[j]];
pachet[postas[i].vector[j]] = pachet[postas[i].vector[k]];
pachet[postas[i].vector[k]] = aux;
}
}
}
}
for (i = 0; i < *nrC; i++)
for (j = 0; j < postas[i].nrPachete; j++) {
postas[i].vector[j] = pachet[postas[i].vector[j]].id;
}
for (i = 0; i < *nrC; i++) {
printf("%d %d ", postas[i].id, postas[i].nrPachete);
for (j = 0; j < postas[i].nrPachete; j++)
printf("%d ", postas[i].vector[j]);
printf("\n");
}
}
int main() {
int nrP, nrC;
pach pachet[1600];
post postas[32];
cart cartier[32];
citeste(&nrP, &cartier[32], &pachet[1600], &nrC);
extrage(&nrP, &pachet[1600]);
distribuie(&nrP, &pachet[1600], &postas[32], &nrC, &cartier[32]);
ordoneaza(&pachet[1600], &nrC, &postas[32]);
return (0);
}
Short info on what the program does:
The citeste function should read the cartier and pachet structures. All of them. And then print those in a bit different format.
The extrage function should take every pachet, and use the adresa (written in BINARY) to convert its 3 parts and obtain the strada, numar and idCartier. Then also print those.
Distribuie checks if the pachet is distributed to a postas (distributed means pachet.idCartier == postas.id), if not it distributes it.
Ordoneaza takes every postas's vector and sorts it after the prioritate (or greutate if the prioritate-s are equal).
But it doesn't work as intended and also gives weird Segmentation Faults.
For example if I comment out the distribuie function, it gives me segfault right after extrage. If I put it back, it gives segfault right after doing it. And if I uncomment everything, it gives segfault at the end again.
If anyone actually read all of this and would be willing to reply, I'd highly appreciate it. Any bit of advice helps!
I did not read your code, but your title said you had trouble passing array of structures. I am attaching a working snippet hope it will help you get around your problem.
#include<stdio.h>
typedef struct employee{
int empId;
char name[10];
}EMP;
void arrayOfStruct(EMP *a, int size)
{
printf("%d\t%d",a[0].empId,a[3].empId);
}
int main()
{
EMP NC[4];
NC[0].empId = 9;
NC[3].empId = 2;
arrayOfStruct(&NC[0],sizeof(NC)/sizeof(NC[0]));
}
with the help of size you can never go beyond the memory allocated for structures.
In case you, want to pass higher dimensional arrays, you have to hard code all the size of arrays except the outer most.
void arrayOfStruct(EMP a[][4], int size)
{
// to do
}
int main()
{
EMP NC[2][4];
...
arrayOfStruct(NC,sizeof(NC)/sizeof(NC[0]));
}
as you see, I did not specify the higher most size of array, which I am passing via other arguement.
Why do I need to specify size of inner dimensions ?
Lets take an example, for suppose you have int[4][4], and you are trying to pass array to a function via int[3][], how does a compiler know how many inner blocks to create, in other case via int[][3], the compiler can easily understand that it has to make inner block of size 3 for each outer array.
I would like to fill 2d array, and this is what I do. However, it would give compile errors such as warning: value computed is not used and i dont understand why. I would appreciate if anyone could show me the problem and explain what could be done. thanks!
#include <stdio.h>
#include <string.h>
int main()
{
int array1[4][4];
int len = sizeof(array1) / sizeof(array1[0]);
int wid = sizeof(array1[0]) / sizeof(array1[0][0]);
int i, j , z = 0;
//compile error
for(i = 0, i < len; i++)
{
for(j = 0, j < wid; j++)
{
array1[i][j] = z;
}
z++;
}
int a, b;
for(a = 0, a < len; a++)
{
for(b = 0, b < wid; b++)
{
printf("%d", array1[a][b]);
}
}
return 0;
}
You have put a comma after the initialization part of each of your for statements. You should put a semicolon. For example, you wrote this:
for(i = 0, i < len; i++)
You need to change it to this:
for(i = 0; i < len; i++)
Also, you will probably want to print spaces between array elements, and a newline after each row:
for(a = 0; a < len; a++) {
for(b = 0; b < wid; b++) {
printf("%d ", array1[a][b]);
}
printf("\n");
}