I'm building a program that is saving information on a matrix of Pixels (a struct). A pixel must have its color (another struct) the color is a struct with three integers (red=vermelho, green=verde and blue=azul). But when I set them their value change right after the end of the for.
For example, if I put the value 250 on all the red attributes of pixels it somehow changes if I print them after the for is finished if I print them while the for is running the values are right.
I'm also reading the information of the value of the red, green and blue values of a file, but I printed them and they are right.
Bellow are the functions that I'm using, and I'm having problems in the function clear from it I'm getting "250 0 0" (the right value) for all the pixels inside the for but the values change being sometimes "250 0 0", "0 250 0" and "250 250 0" in the second for inside the clear function.
I've tried printing all the variables, but it seems they somehow magically change after I set them in the first for. I'm not really experienced at C so I'm really lost right now.
typedef struct cor{
int vermelho;
int verde;
int azul;
} Cor;
typedef struct pixel{
Cor cordopixel;
} Pixel;
typedef struct imagem{
Pixel **pintura;
int largura;
int altura;
} Imagem;
void image(FILE *pont_arq, Imagem *desenho){
int i, j, k;
fscanf(pont_arq, "%d %d", &i, &j);
desenho->altura = j; //value equals 400
desenho->largura = i; //value equals 600
printf("Cria imagem %dx%d\n", i, j);
desenho->pintura = calloc(i, sizeof(Pixel*));
for (k = 0; k < i; ++k){
desenho->pintura[k] = calloc(j, sizeof(Pixel));
}
printf("Saiu\n");
}
int* lerIntArquivo(FILE *pont_arq, int inicio, int vezes, int val[]){
if(vezes==inicio-1){
fscanf(pont_arq, "%d", &val[inicio]);
return val;
}else{
fscanf(pont_arq, "%d", &val[inicio]);
lerIntArquivo(pont_arq, inicio+1,vezes, val);
}
}
void clear(FILE *pont_arq, Imagem *desenho){
int val[3], i, j;
lerIntArquivo(pont_arq, 0, 3, val);
printf("Cria imagem");
printf("%d %d %d\n",val[0],val[1], val[2]); //val[0]=250 val[1]=0 val[2]=0
//this for is printing the right values
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
printf("%d %d\n",i,j);
desenho->pintura[i][j].cordopixel.vermelho = val[0];//setting the values
desenho->pintura[i][j].cordopixel.verde = val[1];//setting the values
desenho->pintura[i][j].cordopixel.azul = val[2];//setting the values
printf("%d ", desenho->pintura[i][j].cordopixel.vermelho);
printf("%d ", desenho->pintura[i][j].cordopixel.verde);
printf("%d\n", desenho->pintura[i][j].cordopixel.azul);
}
}
//this for is not printing the right values
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
printf("%d ", desenho->pintura[i][j].cordopixel.vermelho);
printf("%d ", desenho->pintura[i][j].cordopixel.verde);
printf("%d\n", desenho->pintura[i][j].cordopixel.azul);
}
}
printf("\n");
}
There were no error messages, just wrong values.
When you allocate memory for your image the value of largura is the first size of the 2D array and the value of altura is its second size
desenho->altura = j;
desenho->largura = i;
...
desenho->pintura = calloc(i, sizeof(Pixel*));
for (k = 0; k < i; ++k){
desenho->pintura[k] = calloc(j, sizeof(Pixel));
}
I.e. you create an array of [largura][altura] size.
But when you latter work with the array you suddenly reverse their roles
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
...
desenho->pintura[i][j]
I.e. you access it as a [altura][largura] array, which is incorrect.
At some step you managed to swap the values. Most likely, when you allocated the image memory it was supposed to be
desenho->altura = i;
desenho->largura = j;
not the other way around.
Related
I am new to programming and am trying to use two functions for matrix (2D array) operations, where the output of one function is the input for the next.
However, I do not find a way to correctly deliver the values from one function to another. When I print the outputs of the first function in main (), they are correct, but when I input them into the 2nd function and print them, the values make no sense. I have tried it a lot of ways, but it probably fails due to my lack of understanding double pointers.
I am thankful for any hint or advise!
#include <stdio.h>
#include <stdlib.h>
int** td (int r_in, int c_in, int r_p, int c_p, int input[][c_in],int params[][c_p]){
int i, j, k;
int**y_td;
// memory allocation
y_td = (int*)malloc(sizeof(int*)*r_in);
for (i=0; i < r_in; i++){
y_td[i] = (int*)malloc(sizeof(int)*c_p);
}
//
for (i=0; i < r_in; i++){
for (j=0; j < c_p; j++){
y_td[i][j]=0; // Initialization
for (k=0; k < c_in; k++){
y_td[i][j]+= input[i][k]*params[k][j];
}
}
}
return y_td;
}
int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in]){
int x,i,j,k,l,m,n;
int min_len = ((r_in < f_size)? r_in:f_size);
int max_len = ((r_in > f_size)? r_in:f_size);
int r_out = max_len - min_len + 1;//rows_out
int kernel;
int** y_cnv;
// Print input to check if it was correctly transmitted to the function
printf("Input CV (should be equal to TD result):\n");
for (i=0;i<r_in;i++){
for (j=0;j<c_in;j++){
printf("%d ", input[i][j]);
}
printf("\n");
}
printf("\n\n");
//memory allocation
y_cnv = (int*)malloc(sizeof(int*)*r_out);
for (i=0; i < r_out; i++){
y_cnv[i] = (int*)malloc(sizeof(int)*filter);
}
//
for (i=0; i < filter; i++){
for (k=0; k < r_out; k++){
y_cnv [k][i]=0; //initialize
}
for (j = 0; j < c_in; j++){
for (n = min_len-1; n < max_len; n++){
x = n-min_len+1;
for (m= 0; m < r_in; m++){
kernel = (((n-m) < min_len && (n-m) >= 0)? params[i][n-m][j]:0);
y_cnv[x][i] += input[m][j]*kernel;
}
}
}
}
return y_cnv;
}
int main() {
// create test arrays
int A [4][2]= {{1,1},{2,2},{3,3},{4,4}};
int B [2][3]= {{1,2,3},{2,3,4}};
int C [2][2][3]= {{{1,1,1},{2,2,2}},{{3,3,3},{4,4,4}}};
int** matrix;
int i, j;
matrix = td(4,2,2,3,A,B);
// print the result of first function, which is input in 2nd function
printf("The TD result is:\n");
for (i=0;i<4;i++){
for (j=0;j<3;j++){
printf("%d ",matrix[i][j]);
}
printf("\n");
}
printf("\n\n");
matrix = cnv(4,3,2,2,matrix,C);
return 0;
}
I expect the matrix printed in main () after the first function td () to be the same as when I read it in the second function cnv () and print it there, but it is not.
take a look at this question. You were hit by the same underlying problem.
Turning
int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in])
into
int** cnv (int r_in, int c_in, int filter, int f_size, int** input, int params[][f_size][c_in])
fixes the problem you asked for.
The reason is that you allocate an array of pointers called y_td in your first function. Each of this pointers is a number naming a memory segment where you stored some real numbers. By using int input[][c_in] you tell the computer to interpret these pointers as integer numbers and when you print them you get the addresses in memory instead of the expected values, because then input[x][y] is translated to *((int *)input+x*c_in+y).
Please allow me one more comment: You should follow the comments below the question and care for all compiler warnings: If there is a warning you should treat it as an compiler error unless you exactly know what you are doing, especially in C. Your code contains some possible problem sources like the one above.
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 have a 2D array in which many elements are zero. For example:
int array[10][10];
memset(array, 0, 100 * sizeof(int));
array[0][0] = 3;
array[2][8] = 5;
array[4][0] = 4;
How could I print the non-zero (only positive) elements in descending (or ascending) order. I was thinking about something like this:
int xpos, ypos;
while (getMaximumInArray(array, &xpos, &ypos))
{
printf("x=%i y=%i val=%i\n", xpos, ypos, array[xpos][ypos]);
array[xpos][ypos] = 0; // set to 0 to make sure we find the next biggest value.
}
However this makes me loop through the array many times (as much as there are non-zero elements). Would there be a better (ie less operations) way to do this?
EDIT : I forgot to specify that I would like to use the positions in my output; so I need not only the sorted values; but also their indices...
A simple way to make this more efficient is to simply sort the values. Sorting - or copying while sorting - has runtime complexity of O(n log n) which is an improvement over your O(n*n). An easy and efficient way to do that is to copy the non-zero values to a std::multiset and then iterate through it.
Update regarding your edit:
No problem. Simply store an object that contains the value and the indices in the set and supply a comparison functor that uses only the value.
You could create new array and then sort it.
For example:
int array[10][10];
array[0][0] = 3;
array[2][8] = 5;
array[4][0] = 4;
int positive[100];
int k = 0;
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
if(array[i][j] > 0){
positive[k++] = array[i][j];
}
}
}
sort(positive, positive + k);
for(int i = 0; i < k; i++){
printf("%d", positive[i]);
}
There are multiple approaches to this. Denis Gavrus proposed using an array, which is fine, but you can use a vector if you want to be more memory efficient:
Also, if you need to keep your values and their position, you'll need to store them in a struct/class (the ELEMENT struct), which will need a separate comparison class/function.
Here is the container and the comparison function:
struct ELEMENT{ ///Containing the value and the coordinates
int val, i, j;
};
bool cmp(ELEMENT a, ELEMENT b){
return a.val<b.val;
}
And here is the code that processes your data:
const int L=10; ///In case you want to modify the matrix dimensions
int array[L][L]; ///A really bad name for anything
vector<ELEMENT> v; ///The vector containing the sorted values
for(int i=0; i<L; i++) ///Initialize the matrix with 0
for(int j=0; j<L; j++)
array[i][j]=0;
array[0][0] = 3; ///Your values...
array[2][8] = 5;
array[4][0] = 4;
for(int i=0; i<L; i++)
for(int j=0; j<L; j++)
if(array[i][j]!=0)
v.push_back({array[i][j], i, j}); ///Insert into v the non-zero values and the coordinates
sort(v.begin(), v.end(), cmp);
for(ELEMENT i:v)///Your output
printf("%d at position (%d, %d)\n",i.val, i.i, i.j);
Also, you could use a priority queue:
The comparison class for the priority queue:
class cmp{ ///Containing the functor for the priority queue
public:
bool operator()(ELEMENT a, ELEMENT b){
return a.val<b.val;
}
};
The code that does stuff:
const int L=10; ///In case you want to modify the matrix dimensions
int array[L][L]; ///A really bad name for anything
priority_queue<ELEMENT, vector<ELEMENT>, cmp> v; ///The priority queue containing the sorted values
for(int i=0; i<L; i++) ///Initialize the matrix with 0
for(int j=0; j<L; j++)
array[i][j]=0;
array[0][0] = 3; ///Your values...
array[2][8] = 5;
array[4][0] = 4;
for(int i=0; i<L; i++)
for(int j=0; j<L; j++)
if(array[i][j]!=0)
v.push({array[i][j], i, j}); ///Insert into v the non-zero values
for(; !v.empty(); v.pop())
printf("%d at position (%d, %d)\n",v.top().val, v.top().i, v.top().j);
I am working on a class project to solve the wandering Salesman problem, which is basically the TSP, except you don't return to the source. I took the approach of finding all possible permutations of a set of vertices and then iteratively calculating the length and comparing them to find the smallest. I know it's not the best approach, but its what our professor wanted.
When I run the code below, it works fine and gives me the right answers when the input array is less than 7 X 7. But when its 7 X 7, it returns "Bus Error: 10", and if the size is 12 x 12, it returns "Segmentation Fault : 11". I looked up these problems for hours and couldn't figure out what's wrong. I'm not much of an expert in C programming, and I'm honestly really confused with pointers. Thank you so much for the help, I appreciate it greatly!
Oh, and sorry about the messy code.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include<stdlib.h>
int x = 0;
int a[];
void swap (int v[], int i, int j) {
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
/* recursive function to generate permutations */
int* perm (int v[], int n, int i) {
/* this function generates the permutations of the array
* from element i to element n-1
*/
int j;
/* if we are at the end of the array, we have one permutation
* we can use (here we print it; you could as easily hand the
* array off to some other function that uses it for something
*/
if (i == n) {
for (j=0; j<n; j++){ a[x] = v[j]; x++;} // printf ("%d ", v[j]);
// printf ("\n");
}
else
/* recursively explore the permutations starting
* at index i going through index n-1
*/
for (j=i; j<n; j++) {
/* try the array with i and j switched */
swap (v, i, j);
perm (v, n, i+1);
/* swap them back the way they were */
swap (v, i, j);
}
return a;
}
int fact(int n){
if(n==1){
return 1;
}
else{
return n * fact(n-1);
}
}
int findShortestPath(int **v , int length){
int pathArrayMultiplier = 0;
int ShortestPathLength = 99999;
printf("Called");
int arrayOfVertices[length-1];
for(int i=0 ; i<length-1 ; i++){
arrayOfVertices[i] = i+2;
}
int n = fact(length-1);
bool doBreak = false;
int pathArray[length-1];
//printf(" Called 3");
printf(" %d" , n);
int* Answer;
Answer = malloc(sizeof(int *));
Answer = perm(arrayOfVertices , length-1 , 0);
printf("Called 4");
int j =-1;
for(int i=0 ; i< n*(length-1) ; i++){
doBreak = false;
j++;
printf("%d " , *(Answer + i));
pathArray[j] = *(Answer+i);
if(j == length-2)
{
j = -1;
// Check for negative values. If any value is negative, disregard path
int checklength = *((int *)v + 0 *length + (pathArray[0]-1));
if(checklength < 0){
printf("First check called");
continue;}
for(int i =0 ; i<length-2 ; i++){
if(*((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1)) < 0){
doBreak = true;
printf("Second Check called");
break;}
}
if(doBreak) { pathArrayMultiplier++; continue;}
printf("\n");
int pathLength = *((int *)v + 0 *length + (pathArray[0]-1));
for(int i =0 ; i<length-2 ; i++){
pathLength = pathLength + *((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1));}
printf("Path Length is %d\n" , pathLength);
if(pathLength < ShortestPathLength) { ShortestPathLength = pathLength;}
}
}
printf("\n\n Shortest Path Length is %d \n" , ShortestPathLength);
return ShortestPathLength;
}
int main () {
int len = 5;
printf("Array is initialized");
int v[7][7] = {0,7,-1,10,1,-1,-1,7,0,-1,-1,10 ,-1 ,1,-1,-1,0,10,1,10,-1,10,-1,10, 0,8,-1,-1,-1,10,1,8,0,10,-1,-1,-1,10,-1,10,0,70,-1,1,-1,-1,-1, 70 , 0};
printf("Array is initialized");
int **realArrayPointer = v;
findShortestPath(realArrayPointer, 7);
return 0;
}
Your code is a mess and practically unreadable. However, I took it upon myself as a challenge to see if I could spot your bug. What I saw is that you declare an empty array at the top:
int a[];
and then you write to this array:
a[x] = v[j];
x++;
You never even reset x back to 0, anywhere. So basically, right from the start you are writing to unallocated memory, but the bigger your input set, the more unallocated memory you write to.
There could be other problems with your code. I definitely saw a whole bunch of other things that indicated an incorrect understanding of pointers, but they wouldn't necessarily cause a fatal error. Please at the very least get some kind of auto-indent program to make your code readable.
Here is a segment of my (incomplete) code
int rows(int board[][9]){
int badUnits = 0, i = 0, n = 9, j, z = 0;
int (*temp)[9];
//Sort each row of 2d array
for (z; z < n; z++){
for (i; i < n; i++){
for (j = i; j < n; j++){
if (board[z][i] > board[z][j]){
temp = board[z][i];
board[z][i] = board[z][j];
board[z][j] = temp;
}
}
}
}
printf ("%d\n", temp[1][0]);
printf ("%d\n", temp[1][1]);
return badUnits;
}
The function takes a 9*9 array.
I get a segmentation fault when the print statements are executed.
I believe my sort code is correct because it is similar to what I use for 1d arrays and I think everything else is correctly assigned.
So the culprit would be my temp variable. I have gone through and tried to assign values to it, tried to change the type, and have taken into account that the 2d array decays into a pointer but is not actually a pointer.
The conclusion I am left with is that this is a dynamic allocation issue. Can someone please lend a hand and assist me in fixing this? I have exhausted my knowledge base and am stuck.
To clarify: I decided to print the temp variable because I thought it would lend some information. The main problem was that the swap was not working, and I was still left with an unsorted array when I originally attempted to print out the board[][]. I know that board is what I am SUPPOSED to be printing.
Thank you for any help!
You assign an int value to temp
temp = board[z][i]; // Temp now is a what ever value was at
// That location in the array e.g. 42
You then treat temp as if it was the address in memory of an integer array
temp[1][1] // treat temp as a pointer and find the integer
// 10 integers further along then temp.
Also sometime temp will not have been initialised (never assigned to) in this case your going to get unexpected behaviour depending on what the last value stored where temp is now (Lets call it a random number).
Did you mean to output the values in board?
printf ("%d\n", board[1][0]);
printf ("%d\n", board[1][1]);
One thing to notice is that the variable temp will only get assigned to if a swap occurs, if the sorting algorithm was correct that is still a situation that could occur with a input corresponding to a sorted board.
But more importantly, the variable temp is used as an int during the swap. Later that integer value is interpreted as a pointer in the expressions temp[1][0] and temp[1][1], which in all likelihoods is not a valid address. You may want to change temp to be declared as:
int temp;
And figure out exactly what you would like to print. If it is whatever one of the two swapped values was (for the last swapped pair in the loop), then you would print it as:
printf("%d", temp);
Else, you would have to add logic according to what you really want to do.
Note that a single pass of this algorithm would not perform a complete sort, but I guess that's one of the reason why you said the provided code was not complete.
Something like this?
#include <stdio.h>
#include <stdlib.h>
void printArray(int** arr, int w, int h) {
for (int i = 0; i < w; ++i) {
for (int j = 0; j < h; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void sortArray(int** arr, int w, int h) {
for (int row = 0; row < h; ++row) {
for (int col = 0; col < w; ++col) {
for (int i = 0; i < w; ++i) {
if (arr[row][i] > arr[row][col]) {
int tmp = arr[row][col];
arr[row][col] = arr[row][i];
arr[row][i] = tmp;
}
}
}
}
}
int main() {
int w = 9, h = 9;
int** arr = (int**)malloc(sizeof(int*) * w);
for (int i = 0; i < w; ++i) {
arr[i] = (int*)malloc(sizeof(int) * h);
for (int j = 0; j < h; ++j) {
arr[i][j] = rand() % 10;
}
}
printf("Unsorted:\n");
printArray(arr, w, h);
sortArray(arr, w, h);
printf("Sorted:\n");
printArray(arr, w, h);
for (int j = 0; j < h; ++j) {
free(arr[j]);
}
free(arr);
return 0;
}